⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bccollection.cpp

📁 Bookcase 是一个用于KDE的个人的书籍管理。它使用XML文件存储格式
💻 CPP
字号:
/***************************************************************************                              bccollection.cpp                             -------------------    begin                : Sat Sep 15 2001    copyright            : (C) 2001 by Robby Stephenson    email                : robby@periapsis.org ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of version 2 of the GNU General Public License as  * *   published by the Free Software Foundation;                            * *                                                                         * ***************************************************************************/#include "bccollection.h"#include <klocale.h>#include <kdebug.h>#include <qregexp.h>//using the c'tor makes this a custom collectionBCCollection::BCCollection(int id_, const QString& title_, const QString& unitName_,                           const QString& unitTitle_)    : QObject(), m_id(id_), m_title(title_), m_unitName(unitName_),      m_unitTitle(unitTitle_), m_iconName(unitName_) {  m_unitList.setAutoDelete(true);  m_attributeList.setAutoDelete(true);  m_unitGroupDicts.setAutoDelete(true);  // all collections have a title attribute for their units  BCAttribute* att = new BCAttribute(QString::fromLatin1("title"), i18n("Title"));  att->setCategory(i18n("General"));  att->setFlags(BCAttribute::FormatTitle | BCAttribute::NoComplete);  addAttribute(att);}BCCollection::BCCollection(const BCCollection&) : QObject() {  kdWarning() << "BCCollection copy constructor - should not be used!!!" << endl;}BCCollection BCCollection::operator=(const BCCollection& coll_) {  kdWarning() << "BCCollection assignment operator - should not be used!!!" << endl;  return BCCollection(coll_);}BCCollection::~BCCollection() {//  m_unitList.clear();//  m_attributeList.clear();//  m_attributeCategories.clear();//  m_unitGroupDicts.clear();//  m_unitGroups.clear();}BCCollection::CollectionType BCCollection::collectionType() const {  return BCCollection::Base;}bool BCCollection::isBook() const {  return false;}bool BCCollection::isSong() const {  return false;}bool BCCollection::isVideo() const {  return false;}unsigned BCCollection::unitCount() const {  return m_unitList.count();}bool BCCollection::addAttribute(BCAttribute* att_) {  if(!att_) {    return false;  }  // attributeByName() returns 0 if there's no attribute by that name  // this essentially checks for duplicates  if(attributeByName(att_->name())) {    return false;  }  m_attributeList.append(att_);  m_attributeNameDict.insert(att_->name(), att_);  m_attributeTitleDict.insert(att_->title(), att_);  //att_->category() will never be empty  if(m_attributeCategories.contains(att_->category()) == 0) {    m_attributeCategories << att_->category();  }  if(att_->flags() & BCAttribute::AllowGrouped) {    // m_unitGroupDicts autoDeletes each QDict when the BCCollection d'tor is called    BCUnitGroupDict* dict = new BCUnitGroupDict();    // don't autoDelete, since the group is deleted when it becomes    // empty in BCUnit::removeFromGroup()    m_unitGroupDicts.insert(att_->name(), dict);    // cache the possible groups of units    m_unitGroups << att_->name();  }  m_isCustom = true;  return true;}void BCCollection::addUnit(BCUnit* unit_) {  if(!unit_) {    return;  }  if(unit_->collection() != this) {    // should the addUnit() call be done in the BCUnit constructor?    kdWarning() << "BCCollection::addUnit() - unit is not being added to its parent collection" << endl;  }  m_unitList.append(unit_);//  kdDebug() << "BCCollection::addUnit() - added unit (" << unit_->title() << ")" << endl;    populateDicts(unit_);}void BCCollection::removeUnitFromDicts(BCUnit* unit_) {  QPtrListIterator<BCUnitGroup> it(unit_->groups());  BCUnitGroup* group;  while(it.current()) {    group = static_cast<BCUnitGroup*>(it.current());    BCUnitGroupDict* dict = m_unitGroupDicts.find(group->attributeName());    // removeFromGroup will delete the group if it becomes empty    // so just see if there's only one unit in the group, because that    // implies that it will be empty when the unit is removed    // emit signalGroupModified(this, group);    if(group->count() == 1) {      dict->remove(group->groupName());    }    // increment the iterator before calling removeFromGroup since the    // group might be deleted    ++it;    unit_->removeFromGroup(group);  }}// this function gets called whenever a unit is modified. Its purpose is to keep the// groupDicts current. It first removes the unit from every group to which it belongs,// then it repopulates the dicts with the unit's attributesvoid BCCollection::updateDicts(BCUnit* unit_) {//  kdDebug() << "BCCollection::updateDicts" << endl;  if(!unit_) {    return;  }  removeUnitFromDicts(unit_);  populateDicts(unit_);}bool BCCollection::deleteUnit(BCUnit* unit_) {  if(!unit_) {    return false;  }  kdDebug() << "BCCollection::deleteUnit() - deleted unit - " << unit_->title() << endl;  removeUnitFromDicts(unit_);  return m_unitList.remove(unit_);}const BCAttributeList& BCCollection::attributeList() const {  return m_attributeList;}BCAttributeList BCCollection::attributeList(int filter_) const {  BCAttributeList list;  BCAttributeListIterator it(m_attributeList);  for( ; it.current(); ++it) {    if(it.current()->flags() & filter_) {      list.append(it.current());    }  }  return list;}const QStringList& BCCollection::attributeCategories() const {  return m_attributeCategories;}BCAttributeList BCCollection::attributesByCategory(const QString& cat_) const {  BCAttributeList list;  BCAttributeListIterator it(m_attributeList);  for( ; it.current(); ++it) {    if(it.current()->category() == cat_) {      list.append(it.current());    }  }  return list;}QStringList BCCollection::attributeNames() const {//  kdDebug() << "BCCollection::attributeNames()" << endl;  QStringList strlist;  BCAttributeListIterator it(m_attributeList);  for ( ; it.current(); ++it) {    strlist << it.current()->name();  }  return strlist;}QStringList BCCollection::attributeTitles() const {//  kdDebug() << "BCCollection::attributeTitles()" << endl;  QStringList strlist;  BCAttributeListIterator it(m_attributeList);  for( ; it.current(); ++it) {    strlist << it.current()->title();  }  return strlist;}const QString& BCCollection::attributeNameByTitle(const QString& title_) const {  BCAttribute* att = attributeByTitle(title_);  if(!att) {    kdWarning() << "BCCollection::attributeNameByTitle() - no attribute titled " << title_ << endl;  }  return att->name();}const QString& BCCollection::attributeTitleByName(const QString& name_) const {  BCAttribute* att = attributeByName(name_);  if(!att) {    kdWarning() << "BCCollection::attributeTitleByName() - no attribute named " << name_ << endl;  }  return att->title();}QStringList BCCollection::valuesByAttributeName(const QString& name_) const {  QStringList strlist;  QPtrListIterator<BCUnit> it(m_unitList);  for( ; it.current(); ++it) {    QString value = it.current()->attribute(name_);    if(strlist.contains(value) == 0) { // haven't inserted it yet      if(attributeByName(name_)->flags() & BCAttribute::AllowMultiple) {        // the space after the semi-colon is enforced elsewhere        strlist += QStringList::split(QString::fromLatin1("; "), value);      } else { // multiple values not allowed        // no need to call value.simplifyWhiteSpace()        strlist += value;      }    }  } // end unit loop  return strlist;}BCAttribute* const BCCollection::attributeByName(const QString& name_) const {  return m_attributeNameDict.isEmpty() ? 0 : m_attributeNameDict.find(name_);}BCAttribute* const BCCollection::attributeByTitle(const QString& title_) const {  return m_attributeTitleDict.isEmpty() ? 0 : m_attributeTitleDict.find(title_);}bool BCCollection::isAllowed(const QString& key_, const QString& value_) const {  // empty string is always allowed  if(value_.isEmpty()) {    return true;  }  // find the attribute with a name of 'key_'  BCAttribute* att = attributeByName(key_);  // if the type is not multiple choice or if value_ is allowed, return true  if(att && (att->type() != BCAttribute::Choice || att->allowed().contains(value_))) {    return true;  }  return false;}bool BCCollection::isCustom() const {  return m_isCustom;}int BCCollection::id() const {  return m_id;}const QString& BCCollection::title() const {  return m_title;}void BCCollection::setTitle(const QString& title_) {  m_title = title_;}const QString& BCCollection::unitName() const {  return m_unitName;}const QString& BCCollection::unitTitle() const {  return m_unitTitle;}const QString& BCCollection::iconName() const {  return m_iconName;}void BCCollection::setIconName(const QString& name_) {  if(name_ != iconName()) {    m_isCustom = true;  }  m_iconName = name_;}const QString& BCCollection::defaultGroupAttribute() const {  return m_defaultGroupAttribute;}void BCCollection::setDefaultGroupAttribute(const QString& name_) {  // the collection is now custom if the default UnitGroup was already set and  // this is a new value  if(!m_defaultGroupAttribute.isEmpty() && name_ != m_defaultGroupAttribute) {    m_isCustom = true;  }  m_defaultGroupAttribute = name_;}const BCUnitList& BCCollection::unitList() const {  return m_unitList;}const QStringList& BCCollection::unitGroups() const {  return m_unitGroups;}BCUnitGroupDict* const BCCollection::unitGroupDictByName(const QString& name_) const {  return m_unitGroupDicts.isEmpty() ? 0 : m_unitGroupDicts.find(name_);}void BCCollection::populateDicts(BCUnit* unit_) {//  kdDebug() << "BCCollection::populateDicts" << endl;  if(m_unitGroupDicts.isEmpty()) {    return;  }  // iterate over all the possible groupDicts  // for each dict, get the value of that attribute for the unit  // if multiple values are allowed, split the value and then insert the  // unit pointer into the dict for each value  QDictIterator<BCUnitGroupDict> dictIt(m_unitGroupDicts);  for( ; dictIt.current(); ++dictIt) {    BCUnitGroupDict* dict = dictIt.current();    QString attName = dictIt.currentKey();    QStringList groups = unit_->groupsByAttributeName(attName);    QStringList::Iterator groupIt;    for(groupIt = groups.begin(); groupIt != groups.end(); ++groupIt) {      QString groupName = static_cast<QString>(*groupIt);//      kdDebug() << "\tnew group - " << groupName << endl;      BCUnitGroup* group;      // surely there's a more efficient way of doing this      // app crashes if find() is called on an empty dict      if(dict->isEmpty()) {        group = new BCUnitGroup(groupName, attName);        dict->insert(groupName, group);      } else {        group = dict->find(groupName);        if(!group) {          group = new BCUnitGroup(groupName, attName);          dict->insert(groupName, group);        }      }      unit_->addToGroup(group);    } // end group loop  } // end dict loop}QString BCCollection::emptyGroupName() {  return i18n("(Empty)");}void BCCollection::groupModified(BCUnitGroup* group_) {  emit signalGroupModified(this, group_);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -