You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
586 lines
17 KiB
586 lines
17 KiB
/***************************************************************************
|
|
* Copyright (C) 2005-2007 by Tarek Saidi *
|
|
* tarek.saidi@arcor.de *
|
|
* *
|
|
* 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; version 2 of the License. *
|
|
* *
|
|
* 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; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
|
|
|
|
#include "EntryView.h"
|
|
#include "GroupView.h"
|
|
#include "dialogs/EditGroupDlg.h"
|
|
|
|
#include <QBrush>
|
|
#include <QHeaderView>
|
|
|
|
#define INSERT_AREA_WIDTH 4
|
|
|
|
KeepassGroupView::KeepassGroupView(QWidget* parent):QTreeWidget(parent){
|
|
db=NULL;
|
|
ContextMenu=new QMenu(this);
|
|
ContextMenuSearchGroup=new QMenu(this);
|
|
connect(this,SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),this,SLOT(OnCurrentGroupChanged(QTreeWidgetItem*)));
|
|
connect(this,SIGNAL(itemExpanded(QTreeWidgetItem*)),this,SLOT(OnItemExpanded(QTreeWidgetItem*)));
|
|
connect(this,SIGNAL(itemCollapsed(QTreeWidgetItem*)),this,SLOT(OnItemCollapsed(QTreeWidgetItem*)));
|
|
}
|
|
|
|
void KeepassGroupView::createItems(){
|
|
clear();
|
|
Items.clear();
|
|
InsLinePos=-1;
|
|
QList<IGroupHandle*> groups=db->groups();
|
|
for(int i=0;i<groups.size();i++){
|
|
if(groups[i]->parent()==NULL){
|
|
Items.append(new GroupViewItem(this));
|
|
Items.back()->setText(0,groups[i]->title());
|
|
Items.back()->GroupHandle=groups[i];
|
|
addChildren(Items.back());
|
|
}
|
|
}
|
|
for(int i=0;i<Items.size();i++){
|
|
Items[i]->setIcon(0,db->icon(Items[i]->GroupHandle->image()));
|
|
Items[i]->setExpanded(Items[i]->GroupHandle->expanded());
|
|
}
|
|
SearchResultItem=new GroupViewItem();
|
|
retranslateUi();
|
|
}
|
|
|
|
void KeepassGroupView::retranslateUi() {
|
|
SearchResultItem->setText(0,tr("Search Results"));
|
|
}
|
|
|
|
void KeepassGroupView::updateIcons(){
|
|
for(int i=0;i<Items.size();i++){
|
|
Items[i]->setIcon(0,db->icon(Items[i]->GroupHandle->image()));
|
|
}
|
|
}
|
|
|
|
void KeepassGroupView::showSearchResults(){
|
|
if(topLevelItem(topLevelItemCount()-1)!=SearchResultItem){
|
|
addTopLevelItem(SearchResultItem);
|
|
}
|
|
setCurrentItem(SearchResultItem);
|
|
emit searchResultsSelected();
|
|
}
|
|
|
|
void KeepassGroupView::addChildren(GroupViewItem* item){
|
|
QList<IGroupHandle*>children=item->GroupHandle->children();
|
|
if(!children.size())
|
|
return;
|
|
for(int i=0; i<children.size(); i++){
|
|
Items.push_back(new GroupViewItem(item));
|
|
Items.back()->setText(0,children[i]->title());
|
|
Items.back()->GroupHandle=children[i];
|
|
addChildren(Items.back());
|
|
}
|
|
}
|
|
|
|
void KeepassGroupView::OnDeleteGroup(){
|
|
if(config->askBeforeDelete()){
|
|
if(QMessageBox::question(this,tr("Delete?"),
|
|
tr("Are you sure you want to delete this group, all its child groups and all their entries?"),
|
|
QMessageBox::Yes | QMessageBox::No,QMessageBox::No) == QMessageBox::No)
|
|
return;
|
|
}
|
|
GroupViewItem* item=(GroupViewItem*)currentItem();
|
|
if(item){
|
|
db->deleteGroup(item->GroupHandle);
|
|
delete item;
|
|
emit fileModified();
|
|
}
|
|
}
|
|
|
|
void KeepassGroupView::OnHideSearchResults(){
|
|
takeTopLevelItem(topLevelItemCount()-1);
|
|
}
|
|
|
|
void KeepassGroupView::OnNewGroup(){
|
|
CGroup NewGroup;
|
|
CEditGroupDialog dlg(db,&NewGroup,parentWidget());
|
|
if(dlg.exec())
|
|
createGroup(NewGroup.Title, NewGroup.Image, NULL);
|
|
}
|
|
|
|
void KeepassGroupView::OnNewSubgroup(){
|
|
GroupViewItem* parent=(GroupViewItem*)currentItem();
|
|
CGroup NewGroup;
|
|
CEditGroupDialog dlg(db,&NewGroup,parentWidget());
|
|
if(dlg.exec())
|
|
createGroup(NewGroup.Title, NewGroup.Image, parent);
|
|
}
|
|
|
|
void KeepassGroupView::createGroup(const QString& title, quint32 image, GroupViewItem* parent){
|
|
CGroup NewGroup;
|
|
NewGroup.Title = title;
|
|
NewGroup.Image = image;
|
|
|
|
IGroupHandle* group;
|
|
if(parent){
|
|
group=db->addGroup(&NewGroup,parent->GroupHandle);
|
|
Items.append(new GroupViewItem(parent));
|
|
}
|
|
else{
|
|
if(topLevelItemCount()){
|
|
int i=1;
|
|
if(topLevelItem(topLevelItemCount()-i)==SearchResultItem)
|
|
i++;
|
|
if(title!="Backup" && topLevelItem(topLevelItemCount()-i)->text(0)=="Backup")
|
|
i++;
|
|
Items.append(new GroupViewItem(this,topLevelItem(topLevelItemCount()-i)));
|
|
}
|
|
else
|
|
Items.append(new GroupViewItem(this));
|
|
|
|
group = db->addGroup(&NewGroup,NULL);
|
|
}
|
|
|
|
Items.back()->GroupHandle = group;
|
|
Items.back()->setText(0, group->title());
|
|
Items.back()->setIcon(0, db->icon(group->image()));
|
|
emit fileModified();
|
|
}
|
|
|
|
void KeepassGroupView::OnEditGroup(){
|
|
GroupViewItem* item=(GroupViewItem*)currentItem();
|
|
CEditGroupDialog dlg(db,item->GroupHandle,parentWidget());
|
|
int r=dlg.exec();
|
|
if(r){
|
|
item->setIcon(0,db->icon(item->GroupHandle->image()));
|
|
item->setText(0,item->GroupHandle->title());
|
|
if(r==2)emit fileModified();
|
|
}
|
|
}
|
|
|
|
void KeepassGroupView::contextMenuEvent(QContextMenuEvent* e){
|
|
if(!(GroupViewItem*)itemAt(e->pos()))
|
|
return;
|
|
|
|
e->accept();
|
|
if(currentItem()==SearchResultItem)
|
|
ContextMenuSearchGroup->popup(e->globalPos());
|
|
else
|
|
ContextMenu->popup(e->globalPos());
|
|
}
|
|
|
|
void KeepassGroupView::OnCurrentGroupChanged(QTreeWidgetItem* cur){
|
|
if(cur){
|
|
if(cur==SearchResultItem)
|
|
emit searchResultsSelected();
|
|
else
|
|
emit groupChanged(((GroupViewItem*)cur)->GroupHandle);
|
|
}
|
|
else
|
|
emit groupChanged(NULL);
|
|
}
|
|
|
|
|
|
void KeepassGroupView::setCurrentGroup(IGroupHandle* group){
|
|
bool found=false;
|
|
int i;
|
|
for(i=0;i<Items.size();i++)
|
|
if(Items[i]->GroupHandle==group){found=true; break;}
|
|
if(!found)return;
|
|
setCurrentItem(Items[i]);
|
|
}
|
|
|
|
void KeepassGroupView::selectFirstGroup(){
|
|
if (Items.isEmpty())
|
|
return;
|
|
|
|
setCurrentItem(Items[0]);
|
|
}
|
|
|
|
void KeepassGroupView::dragEnterEvent ( QDragEnterEvent * event ){
|
|
LastHoverItem=NULL;
|
|
InsLinePos=-1;
|
|
|
|
if(event->mimeData()->hasFormat("application/x-keepassx-group")){
|
|
DragType=GroupDrag;
|
|
event->acceptProposedAction();
|
|
return;
|
|
}
|
|
if(event->mimeData()->hasFormat("application/x-keepassx-entry")){
|
|
DragType=EntryDrag;
|
|
memcpy(&EntryDragItems,event->mimeData()->data("application/x-keepassx-entry").data(),sizeof(void*));
|
|
event->acceptProposedAction();
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KeepassGroupView::dragLeaveEvent ( QDragLeaveEvent * event ){
|
|
Q_UNUSED(event);
|
|
if(LastHoverItem){
|
|
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
|
|
LastHoverItem->setForeground(0,QBrush(QApplication::palette().color(QPalette::Text)));
|
|
}
|
|
if(InsLinePos!=-1){
|
|
int RemoveLine=InsLinePos;
|
|
InsLinePos=-1;
|
|
viewport()->update(QRegion(0,RemoveLine-2,viewport()->width(),4));
|
|
}
|
|
|
|
}
|
|
|
|
void KeepassGroupView::entryDropEvent( QDropEvent * event ){
|
|
GroupViewItem* Item=(GroupViewItem*)itemAt(event->pos());
|
|
if(!Item){
|
|
event->ignore();
|
|
return;
|
|
}
|
|
else{
|
|
if(Item->GroupHandle==((EntryViewItem*)(*EntryDragItems)[0])->EntryHandle->group())
|
|
return;
|
|
for(int i=0;i<EntryDragItems->size();i++){
|
|
db->moveEntry(((EntryViewItem*)(*EntryDragItems)[i])->EntryHandle,Item->GroupHandle);
|
|
}
|
|
emit entriesDropped();
|
|
emit fileModified();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void KeepassGroupView::dropEvent( QDropEvent * event ){
|
|
if(LastHoverItem){
|
|
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
|
|
LastHoverItem->setForeground(0,QBrush(QApplication::palette().color(QPalette::Text)));
|
|
}
|
|
|
|
if(DragType==EntryDrag){
|
|
entryDropEvent(event);
|
|
return;
|
|
}
|
|
|
|
if(InsLinePos!=-1){
|
|
int RemoveLine=InsLinePos;
|
|
InsLinePos=-1;
|
|
viewport()->update(QRegion(0,RemoveLine-2,viewport()->width(),4));
|
|
}
|
|
GroupViewItem* Item=(GroupViewItem*)itemAt(event->pos());
|
|
|
|
if(!Item){
|
|
qDebug("Append at the end");
|
|
db->moveGroup(DragItem->GroupHandle,NULL,-1);
|
|
if(DragItem->parent()){
|
|
DragItem->parent()->takeChild(DragItem->parent()->indexOfChild(DragItem));
|
|
}
|
|
else{
|
|
takeTopLevelItem(indexOfTopLevelItem(DragItem));
|
|
}
|
|
insertTopLevelItem(topLevelItemCount(),DragItem);
|
|
if(topLevelItemCount()>1){
|
|
if(topLevelItem(topLevelItemCount()-2)==SearchResultItem){
|
|
takeTopLevelItem(topLevelItemCount()-2);
|
|
insertTopLevelItem(topLevelItemCount(),SearchResultItem);
|
|
}
|
|
}
|
|
emit fileModified();
|
|
}
|
|
else{
|
|
if (DragItem->GroupHandle==Item->GroupHandle)
|
|
return;
|
|
|
|
QRect ItemRect=visualItemRect(Item);
|
|
if(event->pos().y()>ItemRect.y()+2 && event->pos().y()<ItemRect.y()+ItemRect.height()-2){
|
|
qDebug("Append as child of '%s'",((char*)Item->text(0).toUtf8().data()));
|
|
db->moveGroup(DragItem->GroupHandle,Item->GroupHandle,-1);
|
|
if(DragItem->parent()){
|
|
DragItem->parent()->takeChild(DragItem->parent()->indexOfChild(DragItem));
|
|
}
|
|
else{
|
|
takeTopLevelItem(indexOfTopLevelItem(DragItem));
|
|
}
|
|
Item->insertChild(Item->childCount(),DragItem);
|
|
emit fileModified();
|
|
}
|
|
else{
|
|
if(event->pos().y()>ItemRect.y()+2){
|
|
qDebug("Insert behind sibling '%s'",((char*)Item->text(0).toUtf8().data()));
|
|
if(DragItem->parent()){
|
|
DragItem->parent()->takeChild(DragItem->parent()->indexOfChild(DragItem));
|
|
}
|
|
else{
|
|
takeTopLevelItem(indexOfTopLevelItem(DragItem));
|
|
}
|
|
if(Item->parent()){
|
|
int index=Item->parent()->indexOfChild(Item)+1;
|
|
db->moveGroup(DragItem->GroupHandle,((GroupViewItem*)Item->parent())->GroupHandle,index);
|
|
Item->parent()->insertChild(index,DragItem);
|
|
}
|
|
else{
|
|
int index=indexOfTopLevelItem(Item)+1;
|
|
db->moveGroup(DragItem->GroupHandle,NULL,index);
|
|
insertTopLevelItem(index,DragItem);
|
|
}
|
|
emit fileModified();
|
|
}
|
|
else{
|
|
qDebug("Insert before sibling '%s'",((char*)Item->text(0).toUtf8().data()));
|
|
if(DragItem->parent()){
|
|
DragItem->parent()->takeChild(DragItem->parent()->indexOfChild(DragItem));
|
|
}
|
|
else{
|
|
takeTopLevelItem(indexOfTopLevelItem(DragItem));
|
|
}
|
|
if(Item->parent()){
|
|
int index=Item->parent()->indexOfChild(Item);
|
|
db->moveGroup(DragItem->GroupHandle,((GroupViewItem*)Item->parent())->GroupHandle,index);
|
|
Item->parent()->insertChild(index,DragItem);
|
|
}
|
|
else{
|
|
int index=indexOfTopLevelItem(Item);
|
|
db->moveGroup(DragItem->GroupHandle,NULL,index);
|
|
insertTopLevelItem(index,DragItem);
|
|
}
|
|
emit fileModified();
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void KeepassGroupView::entryDragMoveEvent(QDragMoveEvent* event){
|
|
|
|
GroupViewItem* Item=(GroupViewItem*)itemAt(event->pos());
|
|
if(!Item){
|
|
if(LastHoverItem){
|
|
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
|
|
LastHoverItem->setForeground(0,QBrush(QApplication::palette().color(QPalette::Text)));
|
|
LastHoverItem=NULL;
|
|
}
|
|
event->ignore();
|
|
return;
|
|
}
|
|
if(Item==SearchResultItem){
|
|
if(LastHoverItem){
|
|
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
|
|
LastHoverItem->setForeground(0,QBrush(QApplication::palette().color(QPalette::Text)));
|
|
LastHoverItem=NULL;
|
|
}
|
|
event->ignore();
|
|
return;
|
|
}
|
|
if(LastHoverItem != Item){
|
|
if(LastHoverItem){
|
|
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
|
|
LastHoverItem->setForeground(0,QBrush(QApplication::palette().color(QPalette::Text)));
|
|
}
|
|
Item->setBackgroundColor(0,QApplication::palette().color(QPalette::Highlight));
|
|
Item->setForeground(0,QBrush(QApplication::palette().color(QPalette::HighlightedText)));
|
|
LastHoverItem=Item;
|
|
}
|
|
event->acceptProposedAction();
|
|
return;
|
|
|
|
}
|
|
|
|
void KeepassGroupView::dragMoveEvent(QDragMoveEvent* event){
|
|
if(DragType==EntryDrag){
|
|
entryDragMoveEvent(event);
|
|
return;
|
|
}
|
|
if(DragItem){
|
|
GroupViewItem* Item=(GroupViewItem*)itemAt(event->pos());
|
|
if(!Item){
|
|
if(LastHoverItem){
|
|
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
|
|
LastHoverItem=NULL;
|
|
}
|
|
if(InsLinePos!=-1){
|
|
int RemoveLine=InsLinePos;
|
|
InsLinePos=-1;
|
|
viewport()->update(QRegion(0,RemoveLine-2,viewport()->width(),4));
|
|
}
|
|
event->acceptProposedAction();
|
|
return;
|
|
}
|
|
if(Item==DragItem || Item==SearchResultItem){
|
|
event->ignore();
|
|
return;
|
|
}
|
|
if(!db->isParent(DragItem->GroupHandle,Item->GroupHandle)){
|
|
QRect ItemRect=visualItemRect(Item);
|
|
if(event->pos().y()>ItemRect.y()+2 && event->pos().y()<ItemRect.y()+ItemRect.height()-2){
|
|
if(InsLinePos!=-1){
|
|
int RemoveLine=InsLinePos;
|
|
InsLinePos=-1;
|
|
viewport()->update(QRegion(0,RemoveLine-2,viewport()->width(),4));
|
|
}
|
|
if(LastHoverItem != Item){
|
|
if(LastHoverItem){
|
|
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
|
|
}
|
|
Item->setBackgroundColor(0,QApplication::palette().color(QPalette::Highlight));
|
|
LastHoverItem=Item;
|
|
}
|
|
}
|
|
else{
|
|
if(LastHoverItem){
|
|
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
|
|
LastHoverItem=NULL;
|
|
}
|
|
if(InsLinePos!=-1){
|
|
int RemoveLine=InsLinePos;
|
|
InsLinePos=-1;
|
|
viewport()->update(QRegion(0,RemoveLine-2,viewport()->width(),4));
|
|
}
|
|
if(event->pos().y()>ItemRect.y()+2){
|
|
InsLinePos=ItemRect.y()+ItemRect.height();
|
|
}
|
|
else{
|
|
InsLinePos=ItemRect.y();
|
|
}
|
|
InsLineStart=ItemRect.x();
|
|
viewport()->update(QRegion(0,InsLinePos-2,viewport()->width(),4));
|
|
}
|
|
event->acceptProposedAction();
|
|
return;
|
|
}
|
|
|
|
}
|
|
event->ignore();
|
|
}
|
|
|
|
void KeepassGroupView::paintEvent(QPaintEvent* event){
|
|
|
|
QTreeWidget::paintEvent(event);
|
|
if(InsLinePos != -1){
|
|
QPainter painter(viewport());
|
|
painter.setBrush(QBrush(QColor(0,0,0),Qt::Dense4Pattern));
|
|
painter.setPen(Qt::NoPen);
|
|
painter.drawRect(InsLineStart,InsLinePos-2,viewport()->width(),4);
|
|
}
|
|
}
|
|
|
|
|
|
void KeepassGroupView::mousePressEvent(QMouseEvent *event){
|
|
if (event->button() == Qt::LeftButton)
|
|
DragStartPos = event->pos();
|
|
QTreeWidget::mousePressEvent(event);
|
|
}
|
|
|
|
void KeepassGroupView::mouseMoveEvent(QMouseEvent *event){
|
|
if (!(event->buttons() & Qt::LeftButton))
|
|
return;
|
|
if ((event->pos() - DragStartPos).manhattanLength()
|
|
< QApplication::startDragDistance())
|
|
return;
|
|
|
|
DragItem=(GroupViewItem*)itemAt(event->pos());
|
|
if(!DragItem)return;
|
|
|
|
if(DragItem==SearchResultItem){
|
|
qDebug("SearchGroup");
|
|
DragItem=NULL;
|
|
return;
|
|
}
|
|
|
|
setCurrentItem(DragItem);
|
|
|
|
QDrag *drag = new QDrag(this);
|
|
QMimeData *mimeData = new QMimeData;
|
|
|
|
mimeData->setData("application/x-keepassx-group",QByteArray());
|
|
drag->setMimeData(mimeData);
|
|
|
|
EventOccurredBlock = true;
|
|
drag->exec(Qt::MoveAction);
|
|
EventOccurredBlock = false;
|
|
}
|
|
|
|
void KeepassGroupView::OnItemExpanded(QTreeWidgetItem* item){
|
|
static_cast<GroupViewItem*>(item)->GroupHandle->setExpanded(true);
|
|
}
|
|
|
|
void KeepassGroupView::OnItemCollapsed(QTreeWidgetItem* item){
|
|
static_cast<GroupViewItem*>(item)->GroupHandle->setExpanded(false);
|
|
}
|
|
|
|
void KeepassGroupView::OnSort() {
|
|
QHash<QTreeWidgetItem*,int> oldIndex;
|
|
for (int i=0; i<Items.size(); i++) {
|
|
if (Items[i]->parent())
|
|
oldIndex.insert(Items[i], Items[i]->parent()->indexOfChild(Items[i]));
|
|
else
|
|
oldIndex.insert(Items[i], invisibleRootItem()->indexOfChild(Items[i]));
|
|
}
|
|
|
|
sortItems(0, Qt::AscendingOrder);
|
|
|
|
bool modified = false;
|
|
QMutableHashIterator<QTreeWidgetItem*, int> i(oldIndex);
|
|
while (i.hasNext()) {
|
|
i.next();
|
|
int newIndex;
|
|
IGroupHandle* parent;
|
|
if (i.key()->parent()) {
|
|
newIndex = i.key()->parent()->indexOfChild(i.key());
|
|
parent = static_cast<GroupViewItem*>(i.key()->parent())->GroupHandle;
|
|
}
|
|
else {
|
|
newIndex = invisibleRootItem()->indexOfChild(i.key());
|
|
parent = NULL;
|
|
}
|
|
|
|
if (newIndex != i.value()) {
|
|
db->moveGroup(static_cast<GroupViewItem*>(i.key())->GroupHandle, parent, newIndex);
|
|
modified = true;
|
|
}
|
|
}
|
|
|
|
if (modified)
|
|
emit fileModified();
|
|
}
|
|
|
|
|
|
|
|
GroupViewItem::GroupViewItem():QTreeWidgetItem(){
|
|
}
|
|
|
|
GroupViewItem::GroupViewItem(QTreeWidget *parent):QTreeWidgetItem(parent){
|
|
}
|
|
|
|
GroupViewItem::GroupViewItem(QTreeWidget *parent, QTreeWidgetItem *preceding):QTreeWidgetItem(parent,preceding){
|
|
}
|
|
|
|
GroupViewItem::GroupViewItem(QTreeWidgetItem *parent):QTreeWidgetItem(parent){
|
|
}
|
|
|
|
GroupViewItem::GroupViewItem(QTreeWidgetItem *parent, QTreeWidgetItem *preceding):QTreeWidgetItem(parent,preceding){
|
|
}
|
|
|
|
bool GroupViewItem::operator<(const QTreeWidgetItem& other) const {
|
|
const GroupViewItem* otherItem = static_cast<const GroupViewItem*>(&other);
|
|
KeepassGroupView* groupView = static_cast<KeepassGroupView*>(treeWidget());
|
|
|
|
// Search result is always at the bottom
|
|
if (this == groupView->SearchResultItem)
|
|
return false;
|
|
if (otherItem == groupView->SearchResultItem)
|
|
return true;
|
|
|
|
// Backup group is always at the bottom but above search results
|
|
if (!parent() && text(0).compare("Backup", Qt::CaseInsensitive) == 0)
|
|
return false;
|
|
if (!other.parent() && other.text(0).compare("Backup", Qt::CaseInsensitive) == 0)
|
|
return true;
|
|
|
|
return QString::localeAwareCompare(text(0), other.text(0)) < 0;
|
|
}
|
|
|