📄 categoryedit_p.cpp
字号:
/************************************************************************ Copyright (C) 2000-2002 Trolltech AS. All rights reserved.**** This file is part of the 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.************************************************************************/#include "categoryedit_p.h"#include <qtopia/categories.h>#include <qtopia/global.h>#include <qdir.h>#include <qcheckbox.h>#include <qlineedit.h>#include <qlistview.h>#include <qstringlist.h>#include <qtoolbutton.h>#include <qmessagebox.h>#include <qapplication.h>#include <sys/types.h>#include <sys/stat.h>#include <stdlib.h>#ifndef Q_OS_WIN32#include <unistd.h>#endifusing namespace Qtopia;enum RenameResult{ Ok, Failed, MadeGlobal};// Note that there is a duplicate of this class in libqtopia to allow access to this private classclass CategoryEditPrivate{public: CategoryEditPrivate( QWidget *parent, const QString &appName ) : mCategories( parent, "" ), mStrApp( appName ), w(parent) { editItem = 0; checkable = TRUE; nameChanged = FALSE; settingItem = FALSE; mCategories.load( categoryFileName() ); } Categories mCategories; QListViewItem *editItem; QString mStrApp; QString mVisible; bool checkable, nameChanged; QWidget *w; QString orgName; bool settingItem;};CategoryEdit::CategoryEdit( QWidget *parent, const char *name ) : CategoryEditBase( parent, name ){ d = 0; lvView->setMinimumHeight( 1 ); connect(lvView, SIGNAL(currentChanged(QListViewItem*)), this, SLOT(enableButtons()));#ifndef QTOPIA_DESKTOP connect( qApp, SIGNAL( categoriesChanged() ), SLOT( reloadCategories() ) );#endif}CategoryEdit::CategoryEdit( const QArray<int> &recCats, const QString &appName, const QString &visibleName, QWidget *parent, const char *name ) : CategoryEditBase( parent, name ){ d = 0; lvView->setMinimumHeight( 1 ); setCategories( recCats, appName, visibleName ); connect(lvView, SIGNAL(currentChanged(QListViewItem*)), this, SLOT(enableButtons()));#ifndef QTOPIA_DESKTOP connect( qApp, SIGNAL( categoriesChanged() ), SLOT( reloadCategories() ) );#endif}void CategoryEdit::reloadCategories(){ if ( !d ) return; QValueList<int> l; for ( QListViewItemIterator it( lvView ); it.current(); ++it ) { if ( reinterpret_cast<QCheckListItem*>(it.current())->isOn() ) l.append( d->mCategories.id( d->mStrApp, it.current()->text(0) ) ); } int i = 0; QArray<int> currentSelected( l.count() ); for ( QValueList<int>::ConstIterator lit = l.begin(); lit != l.end(); ++lit ) currentSelected[(int)i++] = *lit; d->mCategories.load( categoryFileName() ); setCategories( currentSelected, d->mStrApp, d->mVisible );}void CategoryEdit::setCategories( const QArray<int> &recCats, const QString &appName, const QString &visibleName ){ if ( !d ) d = new CategoryEditPrivate( (QWidget*)parent(), name() ); d->mStrApp = appName; d->mVisible = visibleName; QStringList appCats = d->mCategories.labels( d->mStrApp ); QArray<int> cats = d->mCategories.ids(d->mStrApp, appCats); lvView->clear(); QStringList::ConstIterator it; int i, j; for ( i = 0, it = appCats.begin(); it != appCats.end(); i++, ++it ) { QCheckListItem *chk; chk = new QCheckListItem( lvView, (*it), QCheckListItem::CheckBox ); if ( !d->mCategories.isGlobal((*it)) ) chk->setText( 1, tr(d->mVisible) ); else chk->setText( 1, tr("All") ); // Is this record using this category, then we should check it for ( j = 0; j < int(recCats.count()); j++ ) { if ( cats[i] == recCats[j] ) { chk->setOn( true ); break; } } } lvView->setSorting( 0, TRUE ); lvView->sort(); if ( lvView->childCount() < 1 ) txtCat->setEnabled( FALSE ); else { lvView->setSelected( lvView->firstChild(), true ); } enableButtons();}#ifdef QTOPIA_DESKTOPvoid CategoryEdit::setCategories( const QArray<int> &recCats, QString appName, QString visibleName, bool checkable ){ delete d; d = 0; if ( !d ) d = new CategoryEditPrivate( (QWidget*)parent(), name() ); d->mStrApp = appName; d->mVisible = visibleName; d->checkable = checkable; QStringList appCats = d->mCategories.labels( d->mStrApp ); QArray<int> cats = d->mCategories.ids(d->mStrApp, appCats); lvView->clear(); QStringList::ConstIterator it; int i, j; for ( i = 0, it = appCats.begin(); it != appCats.end(); i++, ++it ) { if ( d->checkable ) { QCheckListItem *chk; chk = new QCheckListItem( lvView, (*it), QCheckListItem::CheckBox ); if ( !d->mCategories.isGlobal((*it)) ) chk->setText( 1, tr(d->mVisible) ); else chk->setText( 1, tr("All") ); // Is this record using this category, then we should check it for ( j = 0; j < int(recCats.count()); j++ ) { if ( cats[i] == recCats[j] ) { chk->setOn( true ); break; } } } else { QListViewItem *l = new QListViewItem( lvView, (*it) ); if ( !d->mCategories.isGlobal((*it)) ) l->setText( 1, tr(d->mVisible) ); else l->setText( 1, tr("All") ); } } lvView->setSorting( 0, TRUE ); lvView->sort(); if ( lvView->childCount() < 1 ) txtCat->setEnabled( FALSE ); else { lvView->setSelected( lvView->firstChild(), true ); } enableButtons();}void CategoryEdit::refresh(){ if ( !d ) return; d->mCategories.load( categoryFileName() ); setCategories( QArray<int>(), d->mStrApp, d->mVisible, d->checkable );}#endifCategoryEdit::~CategoryEdit(){ if ( d ) delete d;}void CategoryEdit::slotSetText( QListViewItem *newItem ){ updateInline(); d->editItem = newItem; d->nameChanged = FALSE; if ( !d->editItem ) return; d->orgName = d->editItem->text(0); // avoid textChanged signal (could connect,disconnect, but I suspect this is a bit faster...) d->settingItem = TRUE; txtCat->setText( d->editItem->text(0) ); txtCat->setEnabled( true ); if ( d->editItem->text(1) == tr("All") ) chkGlobal->setChecked( true ); else chkGlobal->setChecked( false ); d->settingItem = FALSE;}void CategoryEdit::slotAdd(){ QString name = tr( "New Category" ); bool insertOk = FALSE; int num = 0; while ( !insertOk ) { if ( num++ > 0 ) name = tr("New Category ") + QString::number(num); if ( chkGlobal->isChecked() ) insertOk = d->mCategories.addGlobalCategory( name ); else insertOk = d->mCategories.addCategory( d->mStrApp, name ); } QListViewItem *chk; if ( d->checkable ) chk = (QListViewItem *) new QCheckListItem( lvView, name, QCheckListItem::CheckBox); else chk = new QListViewItem( lvView, name); if ( !chkGlobal->isChecked() ) chk->setText( 1, tr(d->mVisible) ); else chk->setText( 1, tr("All") ); lvView->setSelected( chk, TRUE ); txtCat->selectAll(); txtCat->setFocus(); d->nameChanged = TRUE; enableButtons();}void CategoryEdit::slotRemove(){ d->editItem = lvView->selectedItem(); if ( d->editItem ) { QListViewItem *nextItem = d->editItem->itemBelow(); if ( !nextItem ) nextItem = d->editItem->itemAbove(); if ( chkGlobal->isChecked() ) { switch( QMessageBox::warning( this, tr( "Removing Category" ), "<qt>" + tr( "Deleting a global category " "will delete it from all applications. " "Any items in this category " "will become unfiled. " "Are you sure you want to do this?") + "</qt>", QMessageBox::Yes, QMessageBox::No | QMessageBox::Default ) ) { case QMessageBox::Yes : break; default: return; } } else { switch( QMessageBox::warning( this, tr( "Removing Category" ), "<qt>" + tr( "Deleting a local category will make " "all items in this category unfiled. " "Are you sure you want to do this?") + "</qt>", QMessageBox::Yes, QMessageBox::No ) ) { case QMessageBox::Yes : break; default: return; } } d->mCategories.removeCategory( d->mStrApp, d->orgName ); d->settingItem = TRUE; delete d->editItem; d->editItem = 0; d->settingItem = FALSE; if ( nextItem ) lvView->setSelected( nextItem, TRUE ); } if ( lvView->childCount() < 1 ) { d->settingItem = TRUE; txtCat->clear(); txtCat->setEnabled( FALSE ); d->settingItem = FALSE; } enableButtons();}void CategoryEdit::slotSetGlobal( bool isChecked ){ if ( d->settingItem ) return; if ( d->editItem ) { if ( isChecked ) { d->editItem->setText( 1, tr("All") ); } else { switch( QMessageBox::warning( this, tr( "Removing Category" ), "<qt>" + tr( "Making a global category local " "will delete it from all other applications " "that may use it. Any items in this category " "will become unfiled. " "Are you sure you want to do this?") + "</qt>", QMessageBox::Yes, QMessageBox::No ) ) { case QMessageBox::Yes : break; default: chkGlobal->setChecked( TRUE ); return; } d->editItem->setText( 1, tr(d->mVisible) ); } d->mCategories.setGlobal( d->mStrApp, d->orgName, isChecked ); }}void CategoryEdit::slotTextChanged( const QString &str){ if ( !d->editItem || d->settingItem ) return; d->nameChanged = TRUE; d->editItem->setText( 0, str);}QArray<int> CategoryEdit::newCategories(){ QArray<int> a; if ( d ) { QStringList sl; d->mCategories.save( categoryFileName() ); QListViewItemIterator it( lvView ); QValueList<int> l; for ( ; it.current(); ++it ) { if ( reinterpret_cast<QCheckListItem*>(it.current())->isOn() ) l.append( d->mCategories.id( d->mStrApp, it.current()->text(0) ) ); } int i = 0; a.resize( l.count() ); for ( QValueList<int>::ConstIterator lit = l.begin(); lit != l.end(); ++lit ) a[(int)i++] = *lit; } return a;}void CategoryEdit::accept(){}#ifdef QTOPIA_DESKTOPstatic QString mCatFileName;void Categories::setCategoryFileName(const QString &s){ mCatFileName = s;}#endifQString categoryFileName(){#ifdef QTOPIA_DESKTOP return mCatFileName;#else QDir dir = QString(QDir::homeDirPath() + "/Settings"); if ( !dir.exists() )#ifndef Q_OS_WIN32 mkdir( dir.path().local8Bit(), 0700 );#else dir.mkdir(dir.path());#endif return dir.path() + "/" + "Categories" + ".xml"; // No tr#endif // QTOPIA_DESKTOP}void CategoryEdit::kludge(){ lvView->setMaximumHeight( 130 );}bool CategoryEdit::tryAccept(){ return updateInline();}bool CategoryEdit::updateInline(){ bool result = TRUE; disconnect( lvView, SIGNAL( selectionChanged(QListViewItem*) ), this, SLOT( slotSetText( QListViewItem* ) ) ); if ( d->nameChanged && d->editItem ) { d->settingItem = TRUE; QString newName = txtCat->text().stripWhiteSpace(); RenameResult r = (RenameResult) tryRename(newName, chkGlobal->isChecked()); if ( r == Ok ) { d->editItem->setText(0, newName ); } else if ( r == Failed ) { d->editItem->setText(0, d->orgName ); txtCat->setText( d->orgName ); result = FALSE; } else if ( r == MadeGlobal ) { d->editItem->setText(0, d->orgName); txtCat->setText( d->orgName ); QListViewItem *c; if ( d->checkable ) c = (QListViewItem *) new QCheckListItem( lvView, newName, QCheckListItem::CheckBox ); else c = new QListViewItem(lvView, newName); c->setText(1, tr("All") ); result = FALSE; } d->settingItem = FALSE; } connect( lvView, SIGNAL( selectionChanged(QListViewItem*) ), this, SLOT( slotSetText( QListViewItem* ) ) ); return result;}static bool contains(const Categories &c, const QString &label){ if ( c.globalGroup().contains(label) ) return TRUE; for ( QMap<QString, CategoryGroup>::ConstIterator it = c.appGroupMap().begin(); it != c.appGroupMap().end(); ++it ) { if ( (*it).contains(label) ) return TRUE; } return FALSE;}static void setGlobal(Categories &c, const QString &catname){ for ( QMap<QString, CategoryGroup>::ConstIterator it = c.appGroupMap().begin(); it != c.appGroupMap().end(); ++it ) { if ( (*it).contains(catname) ) { c.setGlobal( it.key(), catname, TRUE ); return; } }}int CategoryEdit::tryRename(const QString &newName, bool global){ QString name = newName.stripWhiteSpace(); if ( name == d->orgName ) return (int) Ok; if (name.isEmpty() ) return (int) Failed; if ( contains(d->mCategories, newName) && !d->mCategories.globalGroup().contains(newName) && !d->mCategories.appGroupMap()[d->mStrApp].contains(newName) ) { switch( QMessageBox::warning( d->w, tr("Duplicate categories"), tr("<qt>There already exists a local category named" " <b>%1</b> in another application.<p>" "Make that category a global group?</qt>").arg(newName), QMessageBox::Yes, QMessageBox::No) ) { case QMessageBox::Yes: setGlobal(d->mCategories, newName); return (int) MadeGlobal; case QMessageBox::No: return (int) Failed; } } bool success; if ( global ) { success = d->mCategories.renameGlobalCategory( d->orgName, newName ); } else { success = d->mCategories.renameCategory( d->mStrApp, d->orgName, newName ); } if ( !success ) { QMessageBox::warning( d->w, tr("Duplicate categories"), tr("There is already a category named\n" "%1.\n" "Please choose another name, or delete\n" "the duplicate.").arg(newName) ); return (int) Failed; } else return (int) Ok;}void CategoryEdit::enableButtons(){ cmdDel->setEnabled(lvView->selectedItem() != 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -