add more spacing
[personal-kdebase.git] / workspace / kcontrol / kfontinst / kcmfontinst / GroupList.cpp
blob1ac80203ea3ef341cfbdb07e522e290ccf483782
1 /*
2 * KFontInst - KDE Font Installer
4 * Copyright 2003-2007 Craig Drummond <craig@kde.org>
6 * ----
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"
25 #include "FontList.h"
26 #include <KDE/KGlobal>
27 #include <KDE/KStandardDirs>
28 #include <KDE/KLocale>
29 #include <KDE/KMimeType>
30 #include <KDE/KIconLoader>
31 #include <kde_file.h>
32 #include <KDE/KMessageBox>
33 #include <KDE/KInputDialog>
34 #include <KDE/KSaveFile>
35 #include <QtGui/QFont>
36 #include <QtGui/QFontDatabase>
37 #include <QtGui/QDropEvent>
38 #include <QtGui/QHeaderView>
39 #include <QtGui/QMenu>
40 #include <QtGui/QApplication>
41 #include <QtXml/QDomElement>
42 #include <QtCore/QTextStream>
43 #include <QtCore/QDir>
44 #include <QtGui/QPainter>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <utime.h>
48 #include "FcEngine.h"
49 #include "Misc.h"
50 #include "KfiConstants.h"
51 #include <config-workspace.h>
53 namespace KFI
56 #define GROUPS_DOC "groups"
57 #define GROUP_TAG "group"
58 #define NAME_ATTR "name"
59 #define FAMILY_TAG "family"
61 enum EGroupColumns
63 COL_GROUP_NAME
66 CGroupListItem::CGroupListItem(const QString &name)
67 : itsName(name),
68 itsType(CUSTOM),
69 itsHighlighted(false),
70 itsStatus(CFamilyItem::ENABLED)
72 itsData.validated=false;
75 CGroupListItem::CGroupListItem(EType type, CGroupList *p)
76 : itsType(type),
77 itsHighlighted(false),
78 itsStatus(CFamilyItem::ENABLED)
80 switch(itsType)
82 case ALL:
83 itsName=i18n("All Fonts");
84 break;
85 case PERSONAL:
86 itsName=i18n("Personal Fonts");
87 break;
88 case SYSTEM:
89 itsName=i18n("System Fonts");
90 break;
91 case STANDARD_TITLE:
92 itsName=i18nc("Title for a group that contains \"All Fonts\", \"Personal Fonts\", \"System Fonts\" and \"Unclassified\"", "Standard:");
93 break;
94 case GROUPS_TITLE:
95 itsName=i18n("Custom:");
96 break;
97 default:
98 itsName=i18n("Unclassified");
100 itsData.parent=p;
103 bool CGroupListItem::hasFont(const CFontItem *fnt) const
105 switch(itsType)
107 case CUSTOM:
108 return itsFamilies.contains(fnt->family());
109 case PERSONAL:
110 return !fnt->isSystem();
111 case SYSTEM:
112 return fnt->isSystem();
113 case ALL:
114 return true;
115 case UNCLASSIFIED:
117 QList<CGroupListItem *>::ConstIterator it(itsData.parent->itsGroups.begin()),
118 end(itsData.parent->itsGroups.end());
120 for(; it!=end; ++it)
121 if((*it)->isCustom() && (*it)->families().contains(fnt->family()))
122 return false;
123 return true;
125 default:
126 return false;
128 return false;
131 void CGroupListItem::updateStatus(QSet<QString> &enabled, QSet<QString> &disabled, QSet<QString> &partial)
133 QSet<QString> families(itsFamilies);
135 if(0!=families.intersect(partial).count())
136 itsStatus=CFamilyItem::PARTIAL;
137 else
139 families=itsFamilies;
141 bool haveEnabled(0!=families.intersect(enabled).count());
143 families=itsFamilies;
145 bool haveDisabled(0!=families.intersect(disabled).count());
147 if(haveEnabled && haveDisabled)
148 itsStatus=CFamilyItem::PARTIAL;
149 else if(haveEnabled && !haveDisabled)
150 itsStatus=CFamilyItem::ENABLED;
151 else
152 itsStatus=CFamilyItem::DISABLED;
156 bool CGroupListItem::load(QDomElement &elem)
158 if(elem.hasAttribute(NAME_ATTR))
160 itsName=elem.attribute(NAME_ATTR);
161 addFamilies(elem);
162 return true;
164 return false;
167 bool CGroupListItem::addFamilies(QDomElement &elem)
169 int b4(itsFamilies.count());
171 for(QDomNode n=elem.firstChild(); !n.isNull(); n=n.nextSibling())
173 QDomElement ent=n.toElement();
175 if(FAMILY_TAG==ent.tagName())
176 itsFamilies.insert(ent.text());
178 return b4!=itsFamilies.count();
181 void CGroupListItem::save(QTextStream &str)
183 str << " <"GROUP_TAG" "NAME_ATTR"=\"" << Misc::encodeText(itsName, str) << "\">" << endl;
184 if(itsFamilies.count())
186 QSet<QString>::ConstIterator it(itsFamilies.begin()),
187 end(itsFamilies.end());
189 for(; it!=end; ++it)
190 str << " <"FAMILY_TAG">" << Misc::encodeText(*it, str) << "</"FAMILY_TAG">" << endl;
192 str << " </"GROUP_TAG">" << endl;
195 CGroupList::CGroupList(QWidget *parent)
196 : QAbstractItemModel(parent),
197 itsTimeStamp(0),
198 itsModified(false),
199 itsParent(parent),
200 itsSortOrder(Qt::AscendingOrder)
202 itsSpecialGroups[CGroupListItem::STANDARD_TITLE]=new CGroupListItem(CGroupListItem::STANDARD_TITLE, this);
203 itsGroups.append(itsSpecialGroups[CGroupListItem::STANDARD_TITLE]);
204 itsSpecialGroups[CGroupListItem::ALL]=new CGroupListItem(CGroupListItem::ALL, this);
205 itsGroups.append(itsSpecialGroups[CGroupListItem::ALL]);
206 if(Misc::root())
207 itsSpecialGroups[CGroupListItem::PERSONAL]=
208 itsSpecialGroups[CGroupListItem::SYSTEM]=NULL;
209 else
211 itsSpecialGroups[CGroupListItem::PERSONAL]=new CGroupListItem(CGroupListItem::PERSONAL, this);
212 itsGroups.append(itsSpecialGroups[CGroupListItem::PERSONAL]);
213 itsSpecialGroups[CGroupListItem::SYSTEM]=new CGroupListItem(CGroupListItem::SYSTEM, this);
214 itsGroups.append(itsSpecialGroups[CGroupListItem::SYSTEM]);
216 itsSpecialGroups[CGroupListItem::UNCLASSIFIED]=
217 new CGroupListItem(CGroupListItem::UNCLASSIFIED, this);
218 itsGroups.append(itsSpecialGroups[CGroupListItem::UNCLASSIFIED]);
219 itsSpecialGroups[CGroupListItem::GROUPS_TITLE]=new CGroupListItem(CGroupListItem::GROUPS_TITLE, this);
220 itsGroups.append(itsSpecialGroups[CGroupListItem::GROUPS_TITLE]);
221 // Locate groups.xml file - normall will be ~/.config/fontgroups.xml
222 QString path(KGlobal::dirs()->localxdgconfdir());
224 if(!Misc::dExists(path))
225 Misc::createDir(path);
227 itsFileName=path+'/'+KFI_GROUPS_FILE;
229 rescan();
232 CGroupList::~CGroupList()
234 save();
235 qDeleteAll(itsGroups);
236 itsGroups.clear();
239 int CGroupList::columnCount(const QModelIndex &) const
241 return 1;
244 void CGroupList::update(const QModelIndex &unHighlight, const QModelIndex &highlight)
246 if(unHighlight.isValid())
248 CGroupListItem *grp=static_cast<CGroupListItem *>(unHighlight.internalPointer());
249 if(grp)
250 grp->setHighlighted(false);
251 emit dataChanged(unHighlight, unHighlight);
253 if(highlight.isValid())
255 CGroupListItem *grp=static_cast<CGroupListItem *>(highlight.internalPointer());
256 if(grp)
257 grp->setHighlighted(true);
258 emit dataChanged(highlight, highlight);
262 void CGroupList::updateStatus(QSet<QString> &enabled, QSet<QString> &disabled,
263 QSet<QString> &partial)
265 QList<CGroupListItem *>::Iterator it(itsGroups.begin()),
266 end(itsGroups.end());
268 for(; it!=end; ++it)
269 if((*it)->isCustom())
270 (*it)->updateStatus(enabled, disabled, partial);
272 emit layoutChanged();
275 inline QColor midColour(const QColor &a, const QColor &b)
277 return QColor((a.red()+b.red())>>1, (a.green()+b.green())>>1, (a.blue()+b.blue())>>1);
280 QVariant CGroupList::data(const QModelIndex &index, int role) const
282 if (!index.isValid())
283 return QVariant();
285 CGroupListItem *grp=static_cast<CGroupListItem *>(index.internalPointer());
287 if(grp)
288 switch(index.column())
290 case COL_GROUP_NAME:
291 switch(role)
293 case Qt::BackgroundRole:
294 switch(grp->type())
296 case CGroupListItem::STANDARD_TITLE:
297 case CGroupListItem::GROUPS_TITLE:
299 QPalette pal(QApplication::palette());
301 return midColour(pal.color(QPalette::Active, QPalette::Base),
302 pal.color(QPalette::Active, QPalette::Highlight));
304 default:
305 break;
307 break;
308 case Qt::FontRole:
309 switch(grp->type())
311 case CGroupListItem::STANDARD_TITLE:
312 case CGroupListItem::GROUPS_TITLE:
314 QFont font;
315 font.setPointSizeF(font.pointSizeF()*0.75);
316 font.setBold(true);
317 return font;
319 default:
320 break;
322 break;
323 case Qt::DisplayRole:
324 if(grp->isCustom())
325 if(CFamilyItem::DISABLED==grp->status())
326 if(grp->families().count())
327 return i18n("%1 (Disabled)", grp->name());
328 else
329 return i18n("%1 (Empty)", grp->name());
330 else if(CFamilyItem::PARTIAL==grp->status())
331 return i18n("%1 (Partial)", grp->name());
332 return grp->name();
333 case Qt::DecorationRole:
334 if(grp->highlighted())
335 switch(grp->type())
337 case CGroupListItem::ALL: // Removing from a group
338 return SmallIcon("list-remove");
339 case CGroupListItem::PERSONAL: // Copying/moving
340 case CGroupListItem::SYSTEM: // Copying/moving
341 return SmallIcon(Qt::LeftToRight==QApplication::layoutDirection()
342 ? "go-next" : "go-previous");
343 case CGroupListItem::CUSTOM: // Adding to a group
344 return SmallIcon("list-add");
345 default:
346 break;
348 default:
349 break;
351 break;
353 return QVariant();
356 Qt::ItemFlags CGroupList::flags(const QModelIndex &index) const
358 if (!index.isValid())
359 return Qt::ItemIsEnabled;
361 CGroupListItem *grp=static_cast<CGroupListItem *>(index.internalPointer());
363 if(grp)
364 switch(grp->type())
366 case CGroupListItem::STANDARD_TITLE:
367 case CGroupListItem::GROUPS_TITLE:
368 return Qt::ItemIsEnabled;
369 default:
370 break;
372 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled;
375 QVariant CGroupList::headerData(int section, Qt::Orientation orientation, int role) const
377 if (Qt::Horizontal==orientation && COL_GROUP_NAME==section)
378 switch(role)
380 case Qt::DisplayRole:
381 return i18n("Group");
382 case Qt::TextAlignmentRole:
383 return Qt::AlignLeft;
384 case Qt::WhatsThisRole:
385 return whatsThis();
386 default:
387 break;
390 return QVariant();
393 QModelIndex CGroupList::index(int row, int column, const QModelIndex &parent) const
395 if(!parent.isValid())
397 CGroupListItem *grp=itsGroups.value(row);
399 if(grp)
400 return createIndex(row, column, grp);
403 return QModelIndex();
406 QModelIndex CGroupList::parent(const QModelIndex &) const
408 return QModelIndex();
411 int CGroupList::rowCount(const QModelIndex &) const
413 return itsGroups.count();
416 void CGroupList::rescan()
418 save();
419 load();
420 sort(0, itsSortOrder);
423 void CGroupList::load()
425 time_t ts=Misc::getTimeStamp(itsFileName);
427 if(!ts || ts!=itsTimeStamp)
429 clear();
430 itsTimeStamp=ts;
431 if(load(itsFileName))
432 itsModified=false;
436 bool CGroupList::load(const QString &file)
438 QFile f(file);
439 bool rv(false);
441 if(f.open(QIODevice::ReadOnly))
443 QDomDocument doc;
445 if(doc.setContent(&f))
446 for(QDomNode n=doc.documentElement().firstChild(); !n.isNull(); n=n.nextSibling())
448 QDomElement e=n.toElement();
450 if(GROUP_TAG==e.tagName() && e.hasAttribute(NAME_ATTR))
452 QString name(e.attribute(NAME_ATTR));
454 CGroupListItem *item=find(name);
456 if(!item)
458 item=new CGroupListItem(name);
459 itsGroups.append(item);
460 rv=true;
463 if(item->addFamilies(e))
464 rv=true;
468 return rv;
471 bool CGroupList::save()
473 if(itsModified && save(itsFileName, NULL))
475 itsTimeStamp=Misc::getTimeStamp(itsFileName);
476 return true;
478 return false;
481 bool CGroupList::save(const QString &fileName, CGroupListItem *grp)
483 KSaveFile file(fileName);
485 if(file.open())
487 QTextStream str(&file);
489 str << "<"GROUPS_DOC">" << endl;
491 if(grp)
492 grp->save(str);
493 else
495 QList<CGroupListItem *>::Iterator it(itsGroups.begin()),
496 end(itsGroups.end());
498 for(; it!=end; ++it)
499 if((*it)->isCustom())
500 (*it)->save(str);
502 str << "</"GROUPS_DOC">" << endl;
503 itsModified=false;
504 return file.finalize();
507 return false;
510 void CGroupList::merge(const QString &file)
512 if(load(file))
514 itsModified=true;
515 sort(0, itsSortOrder);
519 void CGroupList::clear()
521 beginRemoveRows(QModelIndex(), 0, itsGroups.count());
522 endRemoveRows();
523 itsGroups.removeFirst(); // Remove STANDARD_TITLE
524 itsGroups.removeFirst(); // Remove all
525 if(itsSpecialGroups[CGroupListItem::SYSTEM])
527 itsGroups.removeFirst(); // Remove personal
528 itsGroups.removeFirst(); // Remove system
530 itsGroups.removeFirst(); // Remove unclassif...
531 itsGroups.removeFirst(); // Remove GROUPS_TITLE
532 qDeleteAll(itsGroups);
533 itsGroups.clear();
534 itsGroups.append(itsSpecialGroups[CGroupListItem::STANDARD_TITLE]);
535 itsGroups.append(itsSpecialGroups[CGroupListItem::ALL]);
536 if(itsSpecialGroups[CGroupListItem::SYSTEM])
538 itsGroups.append(itsSpecialGroups[CGroupListItem::PERSONAL]);
539 itsGroups.append(itsSpecialGroups[CGroupListItem::SYSTEM]);
541 itsGroups.append(itsSpecialGroups[CGroupListItem::UNCLASSIFIED]);
542 itsGroups.append(itsSpecialGroups[CGroupListItem::GROUPS_TITLE]);
545 QModelIndex CGroupList::index(CGroupListItem::EType t)
547 return createIndex(t, 0, itsSpecialGroups[t]);
550 void CGroupList::createGroup(const QString &name)
552 if(!exists(name))
554 itsGroups.append(new CGroupListItem(name));
555 itsModified=true;
556 save();
557 sort(0, itsSortOrder);
561 void CGroupList::renameGroup(const QModelIndex &idx, const QString &name)
563 if(idx.isValid())
565 CGroupListItem *grp=static_cast<CGroupListItem *>(idx.internalPointer());
567 if(grp && grp->isCustom() && grp->name()!=name && !exists(name))
569 grp->setName(name);
570 itsModified=true;
571 save();
572 sort(0, itsSortOrder);
577 bool CGroupList::removeGroup(const QModelIndex &idx)
579 if(idx.isValid())
581 CGroupListItem *grp=static_cast<CGroupListItem *>(idx.internalPointer());
583 if(grp && grp->isCustom() &&
584 KMessageBox::Yes==KMessageBox::warningYesNo(itsParent,
585 i18n("<p>Do you really want to remove \'<b>%1</b>\'?</p>"
586 "<p><i>This will only remove the group, and not "
587 "the actual fonts.</i></p>", grp->name()),
588 i18n("Remove Group"), KGuiItem(i18n("Remove"), "list-remove",
589 i18n("Remove group"))))
591 itsModified=true;
592 itsGroups.removeAll(grp);
593 delete grp;
594 save();
595 sort(0, itsSortOrder);
596 return true;
600 return false;
603 void CGroupList::removeFromGroup(const QModelIndex &group, const QSet<QString> &families)
605 if(group.isValid())
607 CGroupListItem *grp=static_cast<CGroupListItem *>(group.internalPointer());
609 if(grp && grp->isCustom())
611 QSet<QString>::ConstIterator it(families.begin()),
612 end(families.end());
613 bool update(false);
615 for(; it!=end; ++it)
616 if(removeFromGroup(grp, *it))
617 update=true;
619 if(update)
620 emit refresh();
625 QString CGroupList::whatsThis() const
627 return i18n("<h3>Font Groups</h3><p>This list displays the font groups available on your system. "
628 "There are 2 main types of font groups:"
629 "<ul><li><b>Standard</b> are special groups used by the font manager.<ul>%1</ul></li>"
630 "<li><b>Custom</b> are groups created by you. To add a font family to one of "
631 "these groups simply drag it from the list of fonts, and drop "
632 "onto the desired group. To remove a family from the group, drag "
633 "the font onto the \"All Fonts\" group.</li>"
634 "</ul></p>",
635 Misc::root()
636 ? i18n("<li><i>All Fonts</i> contains all the fonts installed on your system.</li>"
637 "<li><i>Unclassified</i> contains all fonts that have not yet been placed "
638 "within a \"Custom\" group.</li>")
639 : i18n("<li><i>All Fonts</i> contains all the fonts installed on your system - "
640 "both \"System\" and \"Personal\".</li>"
641 "<li><i>System</i> contains all fonts that are installed system-wide (i.e. "
642 "available to all users).</li>"
643 "<li><i>Personal</i> contains your personal fonts.</li>"
644 "<li><i>Unclassified</i> contains all fonts that have not yet been placed "
645 "within a \"Custom\" group.</li>"));
648 void CGroupList::addToGroup(const QModelIndex &group, const QSet<QString> &families)
650 if(group.isValid())
652 CGroupListItem *grp=static_cast<CGroupListItem *>(group.internalPointer());
654 if(grp && grp->isCustom())
656 QSet<QString>::ConstIterator it(families.begin()),
657 end(families.end());
658 bool update(false);
660 for(; it!=end; ++it)
661 if(!grp->hasFamily(*it))
663 grp->addFamily(*it);
664 update=true;
665 itsModified=true;
668 if(update)
669 emit refresh();
674 void CGroupList::removeFamily(const QString &family)
676 QList<CGroupListItem *>::ConstIterator it(itsGroups.begin()),
677 end(itsGroups.end());
679 for(; it!=end; ++it)
680 removeFromGroup(*it, family);
683 bool CGroupList::removeFromGroup(CGroupListItem *grp, const QString &family)
685 if(grp && grp->isCustom() && grp->hasFamily(family))
687 grp->removeFamily(family);
688 itsModified=true;
689 return true;
692 return false;
695 static bool groupNameLessThan(const CGroupListItem *f1, const CGroupListItem *f2)
697 return f1 && f2 && (f1->type()<f2->type() ||
698 (f1->type()==f2->type() && QString::localeAwareCompare(f1->name(), f2->name())<0));
701 static bool groupNameGreaterThan(const CGroupListItem *f1, const CGroupListItem *f2)
703 return f1 && f2 && (f1->type()<f2->type() ||
704 (f1->type()==f2->type() && QString::localeAwareCompare(f1->name(), f2->name())>0));
707 void CGroupList::sort(int, Qt::SortOrder order)
709 itsSortOrder=order;
711 qSort(itsGroups.begin(), itsGroups.end(),
712 Qt::AscendingOrder==order ? groupNameLessThan : groupNameGreaterThan);
714 emit layoutChanged();
717 Qt::DropActions CGroupList::supportedDropActions() const
719 return Qt::CopyAction | Qt::MoveAction;
722 QStringList CGroupList::mimeTypes() const
724 QStringList types;
725 types << KFI_FONT_DRAG_MIME;
726 return types;
729 CGroupListItem * CGroupList::find(const QString &name)
731 QList<CGroupListItem *>::ConstIterator it(itsGroups.begin()),
732 end(itsGroups.end());
734 for(; it!=end; ++it)
735 if((*it)->name()==name)
736 return (*it);
738 return NULL;
741 bool CGroupList::exists(const QString &name)
743 if(NULL!=find(name))
745 KMessageBox::error(itsParent, i18n("<qt>A group named <b>\'%1\'</b> already "
746 "exists.</qt>", name));
747 return true;
750 return false;
753 CGroupListView::CGroupListView(QWidget *parent, CGroupList *model)
754 : QTreeView(parent)
756 setModel(model);
757 sortByColumn(COL_GROUP_NAME, Qt::AscendingOrder);
758 setSelectionMode(QAbstractItemView::SingleSelection);
759 resizeColumnToContents(COL_GROUP_NAME);
760 setSortingEnabled(true);
761 setAllColumnsShowFocus(true);
762 setAlternatingRowColors(true);
763 setAcceptDrops(true);
764 setDragDropMode(QAbstractItemView::DropOnly);
765 setDropIndicatorShown(true);
766 setDragEnabled(false);
767 header()->setSortIndicatorShown(true);
768 setRootIsDecorated(false);
769 itsMenu=new QMenu(this);
771 itsDeleteAct=itsMenu->addAction(KIcon("list-remove"), i18n("Remove"),
772 this, SIGNAL(del()));
773 itsEnableAct=itsMenu->addAction(KIcon("enablefont"), i18n("Enable"),
774 this, SIGNAL(enable()));
775 itsDisableAct=itsMenu->addAction(KIcon("disablefont"), i18n("Disable"),
776 this, SIGNAL(disable()));
777 itsMenu->addSeparator();
778 itsRenameAct=itsMenu->addAction(i18n("Rename..."), this, SLOT(rename()));
779 itsMenu->addSeparator();
780 itsPrintAct=itsMenu->addAction(KIcon("document-print"), i18n("Print..."),
781 this, SIGNAL(print()));
783 itsActionMenu=new QMenu(this);
784 itsActionMenu->addAction(KIcon("goto-page"), i18n("Move Here"), this, SIGNAL(moveFonts()));
785 itsActionMenu->addAction(KIcon("edit-copy"), i18n("Copy Here"), this, SIGNAL(copyFonts()));
786 itsActionMenu->addSeparator();
787 itsActionMenu->addAction(KIcon("process-stop"), i18n("Cancel"));
789 setWhatsThis(model->whatsThis());
790 header()->setWhatsThis(whatsThis());
791 connect(this, SIGNAL(addFamilies(const QModelIndex &, const QSet<QString> &)),
792 model, SLOT(addToGroup(const QModelIndex &, const QSet<QString> &)));
793 connect(this, SIGNAL(removeFamilies(const QModelIndex &, const QSet<QString> &)),
794 model, SLOT(removeFromGroup(const QModelIndex &, const QSet<QString> &)));
797 CGroupListItem::EType CGroupListView::getType()
799 QModelIndexList selectedItems(selectedIndexes());
801 if(selectedItems.count() && selectedItems.last().isValid())
803 CGroupListItem *grp=static_cast<CGroupListItem *>(selectedItems.last().internalPointer());
805 return grp->type();
808 return CGroupListItem::ALL;
811 void CGroupListView::controlMenu(bool del, bool en, bool dis, bool p)
813 itsDeleteAct->setEnabled(del);
814 itsRenameAct->setEnabled(del);
815 itsEnableAct->setEnabled(en);
816 itsDisableAct->setEnabled(dis);
817 itsPrintAct->setEnabled(p);
820 void CGroupListView::selectionChanged(const QItemSelection &selected,
821 const QItemSelection &deselected)
823 QModelIndexList deselectedItems(deselected.indexes());
825 QAbstractItemView::selectionChanged(selected, deselected);
827 QModelIndexList selectedItems(selectedIndexes());
829 if(0==selectedItems.count() && 1==deselectedItems.count())
830 selectionModel()->select(deselectedItems.last(), QItemSelectionModel::Select);
831 else
832 emit itemSelected(selectedItems.count()
833 ? selectedItems.last()
834 : QModelIndex());
837 void CGroupListView::rename()
839 QModelIndex index(currentIndex());
841 if(index.isValid())
843 CGroupListItem *grp=static_cast<CGroupListItem *>(index.internalPointer());
845 if(grp && grp->isCustom())
847 bool ok;
848 QString name(KInputDialog::getText(i18n("Rename Group"),
849 i18n("Please enter a new name for group:"),
850 grp->name(), &ok, this));
852 if(ok && !name.isEmpty() && name!=grp->name())
853 ((CGroupList *)model())->renameGroup(index, name);
858 void CGroupListView::contextMenuEvent(QContextMenuEvent *ev)
860 if(indexAt(ev->pos()).isValid())
861 itsMenu->popup(ev->globalPos());
864 void CGroupListView::dragEnterEvent(QDragEnterEvent *event)
866 if(event->provides(KFI_FONT_DRAG_MIME))
867 event->acceptProposedAction();
870 void CGroupListView::dragMoveEvent(QDragMoveEvent *event)
872 if(event->provides(KFI_FONT_DRAG_MIME))
874 QModelIndex index(indexAt(event->pos()));
876 if(index.isValid())
878 if(COL_GROUP_NAME!=index.column())
879 index=((CGroupList *)model())->createIdx(index.row(), COL_GROUP_NAME, index.internalPointer());
881 CGroupListItem *dest=static_cast<CGroupListItem *>(index.internalPointer());
882 CGroupListItem::EType type=getType();
884 if(dest)
885 if(!selectedIndexes().contains(index))
887 bool ok(true);
889 if(dest->isCustom())
890 emit info(i18n("Drop here to add the selected fonts to \"%1\".", dest->name()));
891 else if(CGroupListItem::CUSTOM==type && dest->isAll())
892 emit info(i18n("Drop here to remove the selected fonts from the current group."));
893 else if(!Misc::root() && dest->isPersonal() && CGroupListItem::SYSTEM==type)
894 emit info(i18n("Drop here to copy, or move, the selected fonts to your personal folder."));
895 else if(!Misc::root() && dest->isSystem() && CGroupListItem::PERSONAL==type)
896 emit info(i18n("Drop here to copy, or move, the selected fonts to the system folder."));
897 else
898 ok=false;
900 if(ok)
902 drawHighlighter(index);
903 event->acceptProposedAction();
904 return;
908 event->ignore();
909 drawHighlighter(QModelIndex());
910 emit info(QString());
914 void CGroupListView::dragLeaveEvent(QDragLeaveEvent *)
916 drawHighlighter(QModelIndex());
917 emit info(QString());
920 void CGroupListView::dropEvent(QDropEvent *event)
922 emit info(QString());
923 drawHighlighter(QModelIndex());
924 if(event->provides(KFI_FONT_DRAG_MIME))
926 event->acceptProposedAction();
928 QSet<QString> families;
929 QByteArray encodedData(event->mimeData()->data(KFI_FONT_DRAG_MIME));
930 QDataStream ds(&encodedData, QIODevice::ReadOnly);
931 QModelIndex from(selectedIndexes().last()),
932 to(indexAt(event->pos()));
934 ds >> families;
935 // Are we mvoeing/copying, removing a font from the current group?
936 if(to.isValid() && from.isValid())
937 if( ((static_cast<CGroupListItem *>(from.internalPointer()))->isSystem() &&
938 (static_cast<CGroupListItem *>(to.internalPointer()))->isPersonal()) ||
939 ((static_cast<CGroupListItem *>(from.internalPointer()))->isPersonal() &&
940 (static_cast<CGroupListItem *>(to.internalPointer()))->isSystem()))
941 itsActionMenu->popup(QCursor::pos());
942 else if((static_cast<CGroupListItem *>(from.internalPointer()))->isCustom() &&
943 !(static_cast<CGroupListItem *>(to.internalPointer()))->isCustom())
944 emit removeFamilies(from, families);
945 else
946 emit addFamilies(to, families);
948 if(isUnclassified())
949 emit unclassifiedChanged();
953 void CGroupListView::drawHighlighter(const QModelIndex &idx)
955 if(itsCurrentDropItem!=idx)
957 ((CGroupList *)model())->update(itsCurrentDropItem, idx);
958 itsCurrentDropItem=idx;
962 bool CGroupListView::viewportEvent(QEvent *event)
964 executeDelayedItemsLayout();
965 return QTreeView::viewportEvent(event);
970 #include "GroupList.moc"