-rw-r--r-- | library/backend/categories.cpp | 8 | ||||
-rw-r--r-- | library/backend/categories.h | 3 |
2 files changed, 11 insertions, 0 deletions
diff --git a/library/backend/categories.cpp b/library/backend/categories.cpp index cce9f38..34ff6fe 100644 --- a/library/backend/categories.cpp +++ b/library/backend/categories.cpp @@ -676,256 +676,264 @@ bool Categories::save( const QString &fname ) const out += "</Categories>\n"; QCString cstr = out.utf8(); total_written = f.writeBlock( cstr.data(), cstr.length() ); if ( total_written != int(cstr.length()) ) { f.close(); QFile::remove( strNewFile ); return FALSE; } f.close(); #ifdef Q_OS_WIN32 QFile::remove( fname ); #endif if ( ::rename( strNewFile.latin1(), fname.latin1() ) < 0 ) { qWarning( "problem renaming file %s to %s", strNewFile.latin1(), fname.latin1()); // remove the tmp file... QFile::remove( strNewFile ); } return TRUE; } /*! Loads the Categories database using \a fname. See categoryFileName() for the default file name string used for the shared category database. Returns FALSE if there is error reading the file or TRUE on success. */ bool Categories::load( const QString &fname ) { QFile file( fname ); if ( !file.open( IO_ReadOnly ) ) { qWarning("Unable to open %s", fname.latin1()); addGlobalCategory(tr("Business")); addGlobalCategory(tr("Personal")); save(fname); return FALSE; } clear(); QByteArray ba = file.readAll(); QString data = QString::fromUtf8( ba.data(), ba.size() ); QChar *uc = (QChar *)data.unicode(); int len = data.length(); // QTime t; // t.start(); QString name; QString id; QString app; int i = 0; while ( (i = data.find( "<Category ", i)) != -1 ) { i += 10; name = QString::null; app = QString::null; while ( 1 ) { // skip white space while ( i < len && (uc[i] == ' ' || uc[i] == '\n' || uc[i] == '\r') ) i++; // if at the end, then done if ( i >= len-2 || (uc[i] == '/' && uc[i+1] == '>') ) break; // we have another attribute read it. int j = i; while ( j < len && uc[j] != '=' ) j++; QString attr = QConstString( uc+i, j-i ).string(); i = ++j; // skip = while ( i < len && uc[i] != '"' ) i++; j = ++i; while ( j < len && uc[j] != '"' ) j++; QString value = Qtopia::plainString( QConstString( uc+i, j-i ).string() ); i = j + 1; // qDebug("attr='%s' value='%s'", attr.latin1(), value.latin1() ); if ( attr == "id" ) id = value; else if ( attr == "app" ) app = value; else if ( attr == "name" ) name = value; } if ( name.isNull() || id.isNull() ) { qWarning("No name or id in the category"); continue; } if ( app.isNull() ) mGlobalCats.add( id.toInt(), name ); else mAppCats[ app ].add( id.toInt(), name ); } return TRUE; } /*! Clear the categories in memory. Equivelent to creating an empty Categories object. */ void Categories::clear() { mGlobalCats.clear(); mAppCats.clear(); } /*! Dump the contents to standard out. Used for debugging only. */ void Categories::dump() const { qDebug("\tglobal categories = %s", mGlobalCats.labels().join(", ").latin1() ); for ( QMap<QString, CategoryGroup>::ConstIterator appsIt = mAppCats.begin(); appsIt != mAppCats.end(); ++appsIt ) { const QString &app = appsIt.key(); QStringList appcats = (*appsIt).labels(); qDebug("\tapp = %s\tcategories = %s", app.latin1(), appcats.join(", ").latin1() ); } } QStringList CheckedListView::checked() const { QStringList strs; for ( QCheckListItem *i = (QCheckListItem *) firstChild(); i; i = (QCheckListItem *)i->nextSibling() ) if ( i->isOn() ) strs += i->text( 0 ); return strs; } void CheckedListView::addCheckableList( const QStringList &options ) { for ( QStringList::ConstIterator it = options.begin(); it != options.end(); ++it ) { (void) new QCheckListItem( this, *it, QCheckListItem::CheckBox ); } } void CheckedListView::setChecked( const QStringList &checked ) { // iterate over all items bool showingChecked = FALSE; for ( QCheckListItem *i = (QCheckListItem *) firstChild(); i; i = (QCheckListItem *)i->nextSibling() ) // see if the item should be checked by searching the // checked list if ( checked.find( i->text( 0 ) ) != checked.end() ) { i->setOn( TRUE ); // make sure it is showing at least one checked item if ( !showingChecked ) { ensureItemVisible( i ); showingChecked = TRUE; } } else i->setOn( FALSE ); } /*! \fn Categories &Categories::operator= ( const Categories &c ) Performs deep copy. */ /*! \fn QStringList Categories::globalCategories() const Returns list of all global category labels */ /*! \fn const QMap<QString, CategoryGroup> &Categories::appGroupMap() const Returns a map of application names to CategoryGroup. The CategoryGroup class defines a map of ids to category labels and category labels to ids. */ /*! \fn const CategoryGroup &Categories::globalGroup() const Returns the global CategoryGroup. The CategoryGroup class defines a map of ids to category labels and category labels to ids. */ /*! \fn void Categories::categoryAdded( const Categories &cats, const QString &appname, int uid) Emitted if a category is added. \a cats is a const reference to this object \a appname is the CategoryGroup application name that the category was added to or QString::null if it was global \a uid is the unique identifier associated with the added category */ /*! \fn void Categories::categoryRemoved( const Categories &cats, const QString &appname, int uid) Emitted if removed category is removed. \a cats is a const reference to this object \a appname is the CategoryGroup application name that the category was removed from or QString::null if it was the global CategoryGroup \a uid is the unique identifier associated with the removed category */ /*! \fn void Categories::categoryRenamed( const Categories &cats, const QString &appname, int uid) Emitted if \a uid in the \a appname CategoryGroup is renamed in \a cats object. \a cats is a const reference to this object \a appname is the CategoryGroup application name that the category was renamed in or QString::null if it was the global CategoryGroup \a uid is the unique identifier associated with the renamed category */ /*! \fn Categories::Categories( QObject *parent=0, const char *name = 0 ) Constructor for an empty Categories object. */ /*! \fn Categories::Categories( const Categories ©From ) Deep copy constructor */ /*! \fn Categories::~Categories() Empty destructor. Call save() before destruction if there are changes that need to be saved. */ /*! \fn CategoryGroup::clear() \internal */ /*! \fn const QMap<int, QString> &CategoryGroup::idMap() const Returns a const reference to the id to label QMap */ /*! \fn CategoryGroup::CategoryGroup() \internal */ /*! \fn CategoryGroup::CategoryGroup(const CategoryGroup &c) \internal */ + +/* ### FIXME properly merge */ +QStringList Categories::labels( const QString & app, const QArray<int> &catids ) const +{ + QStringList strs = mGlobalCats.labels( catids ); + strs += mAppCats[app].labels( catids ); + return strs; +} diff --git a/library/backend/categories.h b/library/backend/categories.h index d5b3669..91c93e7 100644 --- a/library/backend/categories.h +++ b/library/backend/categories.h @@ -1,226 +1,229 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free ** Software Foundation and appearing in the file LICENSE.GPL included ** in the packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A ** PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef QTPALMTOP_CATEGORIES_H #define QTPALMTOP_CATEGORIES_H #include <qstring.h> #include <qstringlist.h> #include <qmap.h> #include <qlistview.h> #include <qarray.h> #include "qpcglobal.h" #include "palmtopuidgen.h" class CategoryGroup; #if defined(QPC_TEMPLATEDLL) // MOC_SKIP_BEGIN template class QPC_EXPORT QMap<int, QString>; template class QPC_EXPORT QMap<QString, int>; template class QPC_EXPORT QMap< QString, CategoryGroup >; // MOC_SKIP_END #endif class QPC_EXPORT CategoryGroup { friend class Categories; public: CategoryGroup(): mIdLabelMap(), mLabelIdMap() { } CategoryGroup( const CategoryGroup &c ) : mIdLabelMap( c.mIdLabelMap), mLabelIdMap( c.mLabelIdMap ) { } void clear() { mIdLabelMap.clear(); mLabelIdMap.clear(); } int add( const QString &label ); bool add( int uid, const QString &label ); bool remove( const QString &label ); bool remove( int uid ); bool rename( int uid, const QString &newLabel ); bool rename( const QString &oldLabel, const QString &newLabel ); bool contains(int id) const; bool contains(const QString &label) const; /** Returns label associated with the uid or QString::null if * not found */ const QString &label(int id) const; /** Returns the uid associated with label or 0 if not found */ int id(const QString &label) const; /** Returns a sorted list of labels */ QStringList labels() const; QStringList labels( const QArray<int> &catids ) const; const QMap<int, QString> &idMap() const { return mIdLabelMap; } private: void insert( int uid, const QString &label ); QMap<int, QString> mIdLabelMap; QMap<QString, int> mLabelIdMap; static Qtopia::UidGen &uidGen() { return sUidGen; } static Qtopia::UidGen sUidGen; }; /* Map from application name to categories */ class QPC_EXPORT Categories : public QObject { Q_OBJECT public: Categories( QObject *parent=0, const char *name = 0 ) : QObject( parent, name ), mGlobalCats(), mAppCats() { } Categories( const Categories ©From ) : QObject( copyFrom.parent() ), mGlobalCats( copyFrom.mGlobalCats ), mAppCats( copyFrom.mAppCats ) { } virtual ~Categories() { } Categories &operator= ( const Categories &c ) { mAppCats = c.mAppCats; mGlobalCats = c.mGlobalCats; return *this; } void clear(); /** Add the category name as long as it doesn't already exist * locally or globally. Return UID if added, 0 if conflicts * (error). */ int addCategory( const QString &appname, const QString &catname); /** Add the category name as long as it doesn't already exist * locally or globally. Return UID if added, 0 if conflicts * (error). */ int addCategory( const QString &appname, const QString &catname, int uid); /** Add the global category just checking that it doesn't * already exist globally. Return UID if added, 0 if conflicts. */ int addGlobalCategory( const QString &catname ); /** Add the global category just checking that it doesn't * already exist globally. Return UID if added, 0 if conflicts. */ int addGlobalCategory( const QString &catname, int uid ); /** Removes the category from the application; if it is not found * in the application, then it removes it from the global list */ bool removeCategory( const QString &appName, const QString &catName, bool checkGlobal = TRUE); bool removeCategory( const QString &appName, int uid ); bool removeGlobalCategory( const QString &catName ); bool removeGlobalCategory( int uid ); QArray<int> ids( const QString &app, const QStringList &labels) const; /** Returns the id associated with the app */ int id( const QString &app, const QString &cat ) const; /** Returns the label associated with the id */ QString label( const QString &app, int id ) const; enum ExtraLabels { NoExtra, AllUnfiled, AllLabel, UnfiledLabel }; /** Returns the sorted list of all categories that are * associated with the app. * If includeGlobal parameter is TRUE then the returned * categories will include the global category items. * If extra = NoExtra, then * If extra = AllUnfiled, then All and Unfiled will be prepended to * the list * If extra = AllLabel, then All is prepended * If extra = UnfiledLabel, then Unfiled is prepended */ QStringList labels( const QString &app, bool includeGlobal = TRUE, ExtraLabels extra = NoExtra ) const; + QStringList labels( const QString &app, + const QArray<int> &catids ) const; + enum DisplaySingle { ShowMulti, ShowAll, ShowFirst }; /** Returns a single string associated with the cat ids for display in * a combobox or any area that requires one string. If catids are empty * then "Unfiled" will be returned. If multiple categories are assigned * then the behavior depends on the DisplaySingle type. * If /a display is set to ShowMulti then " (multi)" appended to the * first string. If /a display is set to ShowAll, then a space seperated * string is returned with all categories. If ShowFirst is returned, * the just the first string is returned. */ QString displaySingle( const QString &app, const QArray<int> &catids, DisplaySingle display ) const; QStringList globalCategories() const { return mGlobalCats.labels();} bool renameCategory( const QString &appname, const QString &oldName, const QString &newName ); bool renameGlobalCategory( const QString &oldName, const QString &newName ); void setGlobal( const QString &appname, const QString &catname, bool value ); bool isGlobal( const QString &catname ) const; /** Returns true if the catname is associated with any application */ bool exists( const QString &catname ) const; bool exists( const QString &appname, const QString &catname) const; bool save( const QString &fname ) const; bool load( const QString &fname ); // for debugging void dump() const; const QMap<QString, CategoryGroup> &appGroupMap() const{ return mAppCats; } const CategoryGroup &globalGroup() const { return mGlobalCats; } signals: /** emitted if added a category; * the second param is the application the category was added to * or null if global * the third param is the uid of the newly added category */ void categoryAdded( const Categories &, const QString &, int ); /** emitted if removed a category * the second param is the application the category was removed from * or null if global * the third param is the uid of the removed category */ void categoryRemoved( const Categories &, const QString &, int ); /** emitted if a category is renamed; the second param is the uid of * the removed category */ void categoryRenamed( const Categories &, const QString &, int ); private: CategoryGroup mGlobalCats; QMap< QString, CategoryGroup > mAppCats; }; class QPC_EXPORT CheckedListView : public QListView { public: void addCheckableList( const QStringList &options ); void setChecked( const QStringList &checked ); QStringList checked() const; }; #endif |