2
* KFontInst - KDE Font Installer
4
* Copyright 2003-2007 Craig Drummond <craig@kde.org>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; see the file COPYING. If not, write to
20
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21
* Boston, MA 02110-1301, USA.
24
#include "GroupList.h"
26
#include <KDE/KGlobal>
27
#include <KDE/KStandardDirs>
28
#include <KDE/KLocale>
29
#include <KDE/KMimeType>
30
#include <KDE/KIconLoader>
32
#include <KDE/KMessageBox>
33
#include <KDE/KSaveFile>
34
#include <QtGui/QFont>
35
#include <QtGui/QFontDatabase>
36
#include <QtGui/QDropEvent>
37
#include <QtGui/QHeaderView>
38
#include <QtGui/QMenu>
39
#include <QtGui/QApplication>
40
#include <QtGui/QStyledItemDelegate>
41
#include <QtGui/QPainter>
42
#include <QtGui/QLinearGradient>
43
#include <QtXml/QDomElement>
44
#include <QtCore/QTextStream>
45
#include <QtCore/QDir>
46
#include <QtCore/QEvent>
52
#include "KfiConstants.h"
53
#include <config-workspace.h>
58
#define GROUPS_DOC "groups"
59
#define GROUP_TAG "group"
60
#define NAME_ATTR "name"
61
#define FAMILY_TAG "family"
70
CGroupListItem::CGroupListItem(const QString &name)
73
itsHighlighted(false),
74
itsStatus(CFamilyItem::ENABLED)
76
itsData.validated=false;
79
CGroupListItem::CGroupListItem(EType type, CGroupList *p)
81
itsHighlighted(false),
82
itsStatus(CFamilyItem::ENABLED)
87
itsName=i18n("All Fonts");
90
itsName=i18n("Personal Fonts");
93
itsName=i18n("System Fonts");
96
itsName=i18n("Unclassified");
101
bool CGroupListItem::hasFont(const CFontItem *fnt) const
106
return itsFamilies.contains(fnt->family());
108
return !fnt->isSystem();
110
return fnt->isSystem();
115
QList<CGroupListItem *>::ConstIterator it(itsData.parent->itsGroups.begin()),
116
end(itsData.parent->itsGroups.end());
119
if((*it)->isCustom() && (*it)->families().contains(fnt->family()))
129
void CGroupListItem::updateStatus(QSet<QString> &enabled, QSet<QString> &disabled, QSet<QString> &partial)
131
QSet<QString> families(itsFamilies);
133
if(0!=families.intersect(partial).count())
134
itsStatus=CFamilyItem::PARTIAL;
137
families=itsFamilies;
139
bool haveEnabled(0!=families.intersect(enabled).count());
141
families=itsFamilies;
143
bool haveDisabled(0!=families.intersect(disabled).count());
145
if(haveEnabled && haveDisabled)
146
itsStatus=CFamilyItem::PARTIAL;
147
else if(haveEnabled && !haveDisabled)
148
itsStatus=CFamilyItem::ENABLED;
150
itsStatus=CFamilyItem::DISABLED;
154
bool CGroupListItem::load(QDomElement &elem)
156
if(elem.hasAttribute(NAME_ATTR))
158
itsName=elem.attribute(NAME_ATTR);
165
bool CGroupListItem::addFamilies(QDomElement &elem)
167
int b4(itsFamilies.count());
169
for(QDomNode n=elem.firstChild(); !n.isNull(); n=n.nextSibling())
171
QDomElement ent=n.toElement();
173
if(FAMILY_TAG==ent.tagName())
174
itsFamilies.insert(ent.text());
176
return b4!=itsFamilies.count();
179
void CGroupListItem::save(QTextStream &str)
181
str << " <"GROUP_TAG" "NAME_ATTR"=\"" << Misc::encodeText(itsName, str) << "\">" << endl;
182
if(itsFamilies.count())
184
QSet<QString>::ConstIterator it(itsFamilies.begin()),
185
end(itsFamilies.end());
188
str << " <"FAMILY_TAG">" << Misc::encodeText(*it, str) << "</"FAMILY_TAG">" << endl;
190
str << " </"GROUP_TAG">" << endl;
193
CGroupList::CGroupList(QWidget *parent)
194
: QAbstractItemModel(parent),
198
itsSortOrder(Qt::AscendingOrder)
200
itsSpecialGroups[CGroupListItem::ALL]=new CGroupListItem(CGroupListItem::ALL, this);
201
itsGroups.append(itsSpecialGroups[CGroupListItem::ALL]);
203
itsSpecialGroups[CGroupListItem::PERSONAL]=
204
itsSpecialGroups[CGroupListItem::SYSTEM]=NULL;
207
itsSpecialGroups[CGroupListItem::PERSONAL]=new CGroupListItem(CGroupListItem::PERSONAL, this);
208
itsGroups.append(itsSpecialGroups[CGroupListItem::PERSONAL]);
209
itsSpecialGroups[CGroupListItem::SYSTEM]=new CGroupListItem(CGroupListItem::SYSTEM, this);
210
itsGroups.append(itsSpecialGroups[CGroupListItem::SYSTEM]);
212
itsSpecialGroups[CGroupListItem::UNCLASSIFIED]=
213
new CGroupListItem(CGroupListItem::UNCLASSIFIED, this);
214
itsGroups.append(itsSpecialGroups[CGroupListItem::UNCLASSIFIED]);
215
// Locate groups.xml file - normall will be ~/.config/fontgroups.xml
216
QString path(KGlobal::dirs()->localxdgconfdir());
218
if(!Misc::dExists(path))
219
Misc::createDir(path);
221
itsFileName=path+'/'+KFI_GROUPS_FILE;
226
CGroupList::~CGroupList()
229
qDeleteAll(itsGroups);
233
int CGroupList::columnCount(const QModelIndex &) const
235
return NUM_GROUP_COLS;
238
void CGroupList::update(const QModelIndex &unHighlight, const QModelIndex &highlight)
240
if(unHighlight.isValid())
242
CGroupListItem *grp=static_cast<CGroupListItem *>(unHighlight.internalPointer());
244
grp->setHighlighted(false);
245
emit dataChanged(unHighlight, unHighlight);
247
if(highlight.isValid())
249
CGroupListItem *grp=static_cast<CGroupListItem *>(highlight.internalPointer());
251
grp->setHighlighted(true);
252
emit dataChanged(highlight, highlight);
256
void CGroupList::updateStatus(QSet<QString> &enabled, QSet<QString> &disabled,
257
QSet<QString> &partial)
259
QList<CGroupListItem *>::Iterator it(itsGroups.begin()),
260
end(itsGroups.end());
263
if((*it)->isCustom())
264
(*it)->updateStatus(enabled, disabled, partial);
266
emit layoutChanged();
269
inline QColor midColour(const QColor &a, const QColor &b)
271
return QColor((a.red()+b.red())>>1, (a.green()+b.green())>>1, (a.blue()+b.blue())>>1);
274
QVariant CGroupList::data(const QModelIndex &index, int role) const
276
if (!index.isValid())
279
CGroupListItem *grp=static_cast<CGroupListItem *>(index.internalPointer());
282
switch(index.column())
288
if(CGroupListItem::SYSTEM==grp->type())
291
font.setItalic(true);
295
case Qt::SizeHintRole:
296
return SmallIcon("dialog-ok").size()+QSize(0, 4);
298
case Qt::DisplayRole:
300
case Qt::DecorationRole:
301
if(grp->highlighted())
304
case CGroupListItem::ALL: // Removing from a group
305
return SmallIcon("list-remove");
306
case CGroupListItem::PERSONAL: // Copying/moving
307
case CGroupListItem::SYSTEM: // Copying/moving
308
return SmallIcon(Qt::LeftToRight==QApplication::layoutDirection()
309
? "go-next" : "go-previous");
310
case CGroupListItem::CUSTOM: // Adding to a group
311
return SmallIcon("list-add");
318
case CGroupListItem::ALL:
319
return SmallIcon("preferences-desktop-font");
320
case CGroupListItem::PERSONAL:
321
return SmallIcon("user-identity");
322
case CGroupListItem::SYSTEM:
323
return SmallIcon("computer");
324
case CGroupListItem::UNCLASSIFIED:
325
return SmallIcon("fontstatus");
326
case CGroupListItem::CUSTOM:
327
if(0==grp->families().count())
328
return SmallIcon("image-missing");
329
switch(grp->status())
331
case CFamilyItem::PARTIAL:
332
return SmallIcon("dialog-ok", 0, KIconLoader::DisabledState);
333
case CFamilyItem::ENABLED:
334
return SmallIcon("dialog-ok");
335
case CFamilyItem::DISABLED:
336
return SmallIcon("dialog-cancel");
348
bool CGroupList::setData(const QModelIndex &index, const QVariant &value, int role)
350
if(Qt::EditRole==role && index.isValid())
352
QString name(value.toString().trimmed());
356
CGroupListItem *grp=static_cast<CGroupListItem *>(index.internalPointer());
358
if(grp && grp->isCustom() && grp->name()!=name && !exists(name, false))
363
sort(0, itsSortOrder);
371
Qt::ItemFlags CGroupList::flags(const QModelIndex &index) const
373
if (!index.isValid())
374
return Qt::ItemIsEnabled;
376
CGroupListItem *grp=static_cast<CGroupListItem *>(index.internalPointer());
378
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled |
379
(grp && grp->type()==CGroupListItem::CUSTOM ? Qt::ItemIsEditable : Qt::NoItemFlags);
382
QVariant CGroupList::headerData(int section, Qt::Orientation orientation, int role) const
384
if (Qt::Horizontal==orientation && COL_GROUP_NAME==section)
387
case Qt::DisplayRole:
388
return i18n("Group");
389
case Qt::TextAlignmentRole:
390
return Qt::AlignLeft;
391
case Qt::WhatsThisRole:
400
QModelIndex CGroupList::index(int row, int column, const QModelIndex &parent) const
402
if(!parent.isValid())
404
CGroupListItem *grp=itsGroups.value(row);
407
return createIndex(row, column, grp);
410
return QModelIndex();
413
QModelIndex CGroupList::parent(const QModelIndex &) const
415
return QModelIndex();
418
int CGroupList::rowCount(const QModelIndex &) const
420
return itsGroups.count();
423
void CGroupList::rescan()
427
sort(0, itsSortOrder);
430
void CGroupList::load()
432
time_t ts=Misc::getTimeStamp(itsFileName);
434
if(!ts || ts!=itsTimeStamp)
438
if(load(itsFileName))
443
bool CGroupList::load(const QString &file)
448
if(f.open(QIODevice::ReadOnly))
452
if(doc.setContent(&f))
453
for(QDomNode n=doc.documentElement().firstChild(); !n.isNull(); n=n.nextSibling())
455
QDomElement e=n.toElement();
457
if(GROUP_TAG==e.tagName() && e.hasAttribute(NAME_ATTR))
459
QString name(e.attribute(NAME_ATTR));
461
CGroupListItem *item=find(name);
465
item=new CGroupListItem(name);
466
itsGroups.append(item);
470
if(item->addFamilies(e))
478
bool CGroupList::save()
480
if(itsModified && save(itsFileName, NULL))
482
itsTimeStamp=Misc::getTimeStamp(itsFileName);
488
bool CGroupList::save(const QString &fileName, CGroupListItem *grp)
490
KSaveFile file(fileName);
494
QTextStream str(&file);
496
str << "<"GROUPS_DOC">" << endl;
502
QList<CGroupListItem *>::Iterator it(itsGroups.begin()),
503
end(itsGroups.end());
506
if((*it)->isCustom())
509
str << "</"GROUPS_DOC">" << endl;
511
return file.finalize();
517
void CGroupList::merge(const QString &file)
522
sort(0, itsSortOrder);
526
void CGroupList::clear()
528
beginRemoveRows(QModelIndex(), 0, itsGroups.count());
530
itsGroups.removeFirst(); // Remove all
531
if(itsSpecialGroups[CGroupListItem::SYSTEM])
533
itsGroups.removeFirst(); // Remove personal
534
itsGroups.removeFirst(); // Remove system
536
itsGroups.removeFirst(); // Remove unclassif...
537
qDeleteAll(itsGroups);
539
itsGroups.append(itsSpecialGroups[CGroupListItem::ALL]);
540
if(itsSpecialGroups[CGroupListItem::SYSTEM])
542
itsGroups.append(itsSpecialGroups[CGroupListItem::PERSONAL]);
543
itsGroups.append(itsSpecialGroups[CGroupListItem::SYSTEM]);
545
itsGroups.append(itsSpecialGroups[CGroupListItem::UNCLASSIFIED]);
548
QModelIndex CGroupList::index(CGroupListItem::EType t)
550
return createIndex(t, 0, itsSpecialGroups[t]);
553
void CGroupList::createGroup(const QString &name)
557
itsGroups.append(new CGroupListItem(name));
560
sort(0, itsSortOrder);
564
bool CGroupList::removeGroup(const QModelIndex &idx)
568
CGroupListItem *grp=static_cast<CGroupListItem *>(idx.internalPointer());
570
if(grp && grp->isCustom() &&
571
KMessageBox::Yes==KMessageBox::warningYesNo(itsParent,
572
i18n("<p>Do you really want to remove \'<b>%1</b>\'?</p>"
573
"<p><i>This will only remove the group, and not "
574
"the actual fonts.</i></p>", grp->name()),
575
i18n("Remove Group"), KGuiItem(i18n("Remove"), "list-remove",
576
i18n("Remove group"))))
579
itsGroups.removeAll(grp);
582
sort(0, itsSortOrder);
590
void CGroupList::removeFromGroup(const QModelIndex &group, const QSet<QString> &families)
594
CGroupListItem *grp=static_cast<CGroupListItem *>(group.internalPointer());
596
if(grp && grp->isCustom())
598
QSet<QString>::ConstIterator it(families.begin()),
603
if(removeFromGroup(grp, *it))
612
QString CGroupList::whatsThis() const
614
return i18n("<h3>Font Groups</h3><p>This list displays the font groups available on your system. "
615
"There are 2 main types of font groups:"
616
"<ul><li><b>Standard</b> are special groups used by the font manager.<ul>%1</ul></li>"
617
"<li><b>Custom</b> are groups created by you. To add a font family to one of "
618
"these groups simply drag it from the list of fonts, and drop "
619
"onto the desired group. To remove a family from the group, drag "
620
"the font onto the \"All Fonts\" group.</li>"
623
? i18n("<li><i>All Fonts</i> contains all the fonts installed on your system.</li>"
624
"<li><i>Unclassified</i> contains all fonts that have not yet been placed "
625
"within a \"Custom\" group.</li>")
626
: i18n("<li><i>All Fonts</i> contains all the fonts installed on your system - "
627
"both \"System\" and \"Personal\".</li>"
628
"<li><i>System</i> contains all fonts that are installed system-wide (i.e. "
629
"available to all users).</li>"
630
"<li><i>Personal</i> contains your personal fonts.</li>"
631
"<li><i>Unclassified</i> contains all fonts that have not yet been placed "
632
"within a \"Custom\" group.</li>"));
635
void CGroupList::addToGroup(const QModelIndex &group, const QSet<QString> &families)
639
CGroupListItem *grp=static_cast<CGroupListItem *>(group.internalPointer());
641
if(grp && grp->isCustom())
643
QSet<QString>::ConstIterator it(families.begin()),
648
if(!grp->hasFamily(*it))
661
void CGroupList::removeFamily(const QString &family)
663
QList<CGroupListItem *>::ConstIterator it(itsGroups.begin()),
664
end(itsGroups.end());
667
removeFromGroup(*it, family);
670
bool CGroupList::removeFromGroup(CGroupListItem *grp, const QString &family)
672
if(grp && grp->isCustom() && grp->hasFamily(family))
674
grp->removeFamily(family);
682
static bool groupNameLessThan(const CGroupListItem *f1, const CGroupListItem *f2)
684
return f1 && f2 && (f1->type()<f2->type() ||
685
(f1->type()==f2->type() && QString::localeAwareCompare(f1->name(), f2->name())<0));
688
static bool groupNameGreaterThan(const CGroupListItem *f1, const CGroupListItem *f2)
690
return f1 && f2 && (f1->type()<f2->type() ||
691
(f1->type()==f2->type() && QString::localeAwareCompare(f1->name(), f2->name())>0));
694
void CGroupList::sort(int, Qt::SortOrder order)
698
qSort(itsGroups.begin(), itsGroups.end(),
699
Qt::AscendingOrder==order ? groupNameLessThan : groupNameGreaterThan);
701
emit layoutChanged();
704
Qt::DropActions CGroupList::supportedDropActions() const
706
return Qt::CopyAction | Qt::MoveAction;
709
QStringList CGroupList::mimeTypes() const
712
types << KFI_FONT_DRAG_MIME;
716
CGroupListItem * CGroupList::find(const QString &name)
718
QList<CGroupListItem *>::ConstIterator it(itsGroups.begin()),
719
end(itsGroups.end());
722
if((*it)->name()==name)
728
bool CGroupList::exists(const QString &name, bool showDialog)
733
KMessageBox::error(itsParent, i18n("<qt>A group named <b>\'%1\'</b> already "
734
"exists.</qt>", name));
741
class CGroupListViewDelegate : public QStyledItemDelegate
745
CGroupListViewDelegate(QObject *p) : QStyledItemDelegate(p) { }
746
virtual ~CGroupListViewDelegate() { }
748
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const
750
CGroupListItem *grp=static_cast<CGroupListItem *>(idx.internalPointer());
751
QStyleOptionViewItem opt(option);
753
if(grp && grp->isUnclassified())
754
opt.rect.adjust(0, 0, 0, -1);
756
QStyledItemDelegate::paint(painter, opt, idx);
758
if(grp && grp->isUnclassified())
760
opt.rect.adjust(2, 0, -2, 1);
761
painter->setPen(QApplication::palette().color(QPalette::Text));
762
painter->drawLine(opt.rect.bottomLeft(), opt.rect.bottomRight());
766
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &idx) const
768
QSize sz(QStyledItemDelegate::sizeHint(option, idx));
770
CGroupListItem *grp=static_cast<CGroupListItem *>(idx.internalPointer());
772
if(grp && grp->isUnclassified())
773
sz.setHeight(sz.height()+1);
777
static bool isCloseEvent(QKeyEvent *event)
779
return Qt::Key_Tab==event->key() || Qt::Key_Backtab==event->key() ||
780
Qt::Key_Enter==event->key() || Qt::Key_Return==event->key();
783
bool eventFilter(QObject *editor, QEvent *event)
785
if(editor && event && QEvent::KeyPress==event->type() && isCloseEvent(static_cast<QKeyEvent *>(event)) &&
786
qobject_cast<QLineEdit *>(editor))
788
QString text=static_cast<QLineEdit *>(editor)->text().trimmed();
789
if(!text.isEmpty() &&
790
!static_cast<CGroupList *>(static_cast<CGroupListView *>(parent())->model())->exists(text, false))
792
emit commitData(static_cast<QWidget *>(editor));
793
emit closeEditor(static_cast<QWidget *>(editor));
801
CGroupListView::CGroupListView(QWidget *parent, CGroupList *model)
805
setItemDelegate(new CGroupListViewDelegate(this));
806
sortByColumn(COL_GROUP_NAME, Qt::AscendingOrder);
807
setSelectionMode(QAbstractItemView::SingleSelection);
808
setSortingEnabled(true);
809
setAllColumnsShowFocus(true);
810
setAlternatingRowColors(true);
811
setAcceptDrops(true);
812
setDragDropMode(QAbstractItemView::DropOnly);
813
setDropIndicatorShown(true);
814
setDragEnabled(false);
815
header()->setSortIndicatorShown(true);
816
setRootIsDecorated(false);
817
itsMenu=new QMenu(this);
819
itsDeleteAct=itsMenu->addAction(KIcon("list-remove"), i18n("Remove"),
820
this, SIGNAL(del()));
821
itsEnableAct=itsMenu->addAction(KIcon("enablefont"), i18n("Enable"),
822
this, SIGNAL(enable()));
823
itsDisableAct=itsMenu->addAction(KIcon("disablefont"), i18n("Disable"),
824
this, SIGNAL(disable()));
825
itsMenu->addSeparator();
826
itsRenameAct=itsMenu->addAction(i18n("Rename..."), this, SLOT(rename()));
827
itsMenu->addSeparator();
828
itsPrintAct=itsMenu->addAction(KIcon("document-print"), i18n("Print..."),
829
this, SIGNAL(print()));
830
itsMenu->addSeparator();
831
itsExportAct=itsMenu->addAction(KIcon("document-export"), i18n("Export..."),
832
this, SIGNAL(zip()));
834
itsActionMenu=new QMenu(this);
835
itsActionMenu->addAction(KIcon("go-jump"), i18n("Move Here"), this, SIGNAL(moveFonts()));
836
itsActionMenu->addSeparator();
837
itsActionMenu->addAction(KIcon("process-stop"), i18n("Cancel"));
839
setWhatsThis(model->whatsThis());
840
header()->setWhatsThis(whatsThis());
841
connect(this, SIGNAL(addFamilies(const QModelIndex &, const QSet<QString> &)),
842
model, SLOT(addToGroup(const QModelIndex &, const QSet<QString> &)));
843
connect(this, SIGNAL(removeFamilies(const QModelIndex &, const QSet<QString> &)),
844
model, SLOT(removeFromGroup(const QModelIndex &, const QSet<QString> &)));
847
CGroupListItem::EType CGroupListView::getType()
849
QModelIndexList selectedItems(selectedIndexes());
851
if(selectedItems.count() && selectedItems.last().isValid())
853
CGroupListItem *grp=static_cast<CGroupListItem *>(selectedItems.last().internalPointer());
858
return CGroupListItem::ALL;
861
void CGroupListView::controlMenu(bool del, bool en, bool dis, bool p, bool exp)
863
itsDeleteAct->setEnabled(del);
864
itsRenameAct->setEnabled(del);
865
itsEnableAct->setEnabled(en);
866
itsDisableAct->setEnabled(dis);
867
itsPrintAct->setEnabled(p);
868
itsExportAct->setEnabled(exp);
871
void CGroupListView::selectionChanged(const QItemSelection &selected,
872
const QItemSelection &deselected)
874
QModelIndexList deselectedItems(deselected.indexes());
876
QAbstractItemView::selectionChanged(selected, deselected);
878
QModelIndexList selectedItems(selectedIndexes());
880
if(0==selectedItems.count() && 1==deselectedItems.count())
881
selectionModel()->select(deselectedItems.last(), QItemSelectionModel::Select);
883
emit itemSelected(selectedItems.count()
884
? selectedItems.last()
888
void CGroupListView::rename()
890
QModelIndex index(currentIndex());
896
void CGroupListView::contextMenuEvent(QContextMenuEvent *ev)
898
if(indexAt(ev->pos()).isValid())
899
itsMenu->popup(ev->globalPos());
902
void CGroupListView::dragEnterEvent(QDragEnterEvent *event)
904
if(event->provides(KFI_FONT_DRAG_MIME))
905
event->acceptProposedAction();
908
void CGroupListView::dragMoveEvent(QDragMoveEvent *event)
910
if(event->provides(KFI_FONT_DRAG_MIME))
912
QModelIndex index(indexAt(event->pos()));
916
if(COL_GROUP_NAME!=index.column())
917
index=((CGroupList *)model())->createIdx(index.row(), COL_GROUP_NAME, index.internalPointer());
919
CGroupListItem *dest=static_cast<CGroupListItem *>(index.internalPointer());
920
CGroupListItem::EType type=getType();
923
if(!selectedIndexes().contains(index))
928
emit info(i18n("Add to \"%1\".", dest->name()));
929
else if(CGroupListItem::CUSTOM==type && dest->isAll())
930
emit info(i18n("Remove from current group."));
931
else if(!Misc::root() && dest->isPersonal() && CGroupListItem::SYSTEM==type)
932
emit info(i18n("Move to personal folder."));
933
else if(!Misc::root() && dest->isSystem() && CGroupListItem::PERSONAL==type)
934
emit info(i18n("Move to system folder."));
940
drawHighlighter(index);
941
event->acceptProposedAction();
947
drawHighlighter(QModelIndex());
948
emit info(QString());
952
void CGroupListView::dragLeaveEvent(QDragLeaveEvent *)
954
drawHighlighter(QModelIndex());
955
emit info(QString());
958
void CGroupListView::dropEvent(QDropEvent *event)
960
emit info(QString());
961
drawHighlighter(QModelIndex());
962
if(event->provides(KFI_FONT_DRAG_MIME))
964
event->acceptProposedAction();
966
QSet<QString> families;
967
QByteArray encodedData(event->mimeData()->data(KFI_FONT_DRAG_MIME));
968
QDataStream ds(&encodedData, QIODevice::ReadOnly);
969
QModelIndex from(selectedIndexes().last()),
970
to(indexAt(event->pos()));
973
// Are we mvoeing/copying, removing a font from the current group?
974
if(to.isValid() && from.isValid())
976
if( ((static_cast<CGroupListItem *>(from.internalPointer()))->isSystem() &&
977
(static_cast<CGroupListItem *>(to.internalPointer()))->isPersonal()) ||
978
((static_cast<CGroupListItem *>(from.internalPointer()))->isPersonal() &&
979
(static_cast<CGroupListItem *>(to.internalPointer()))->isSystem()))
980
itsActionMenu->popup(QCursor::pos());
981
else if((static_cast<CGroupListItem *>(from.internalPointer()))->isCustom() &&
982
!(static_cast<CGroupListItem *>(to.internalPointer()))->isCustom())
983
emit removeFamilies(from, families);
985
emit addFamilies(to, families);
989
emit unclassifiedChanged();
993
void CGroupListView::drawHighlighter(const QModelIndex &idx)
995
if(itsCurrentDropItem!=idx)
997
((CGroupList *)model())->update(itsCurrentDropItem, idx);
998
itsCurrentDropItem=idx;
1002
bool CGroupListView::viewportEvent(QEvent *event)
1004
executeDelayedItemsLayout();
1005
return QTreeView::viewportEvent(event);
1010
#include "GroupList.moc"