📄 dbview.cpp
字号:
#include "dbview.h"
#include "sman.h"
#include <SMan.rsg>
/***********************************************
Here are the various DBMS panics from Symbian's knowledge
base.
---------------------------------------------------------
ud_std.h (DBMS)
EDbUnimplemented, 0
EDbInvalidColumn, 1
EDbUninitialised, 2
EDbRowLengthOverflow, 3
EDbTooManyKeys, 4
EDbInvalidViewWindowParameters, 5
EDbWrongType, 6
EDbInvalidIncrementalStep, 7
EDbNoColumnsInSeekKey 8
sd_std.h (DBMS-Server)
EDbsUnimplemented, 0
EDbsInvalidColumn, 1
EDbsWrongType, 2
EDbsNoRowData, 3
EDbsNotInUpdate, 4
EDbsBadDescriptor, 5
EDbsBadHandle, 6
EDbsStreamMarkInvalid, 7
EDbsStreamLocationInvalid, 8
EDbsObserverRequestPending 9
us_std.h (DBMS-Store)
EDbUnimplemented, 0
EDbNoStore, 1
EDbCannotSeek, 2
EDbNotFixedFieldType, 3
EDbWrongType 4
ut_std.h (DBMS-Table)
EDbInvalidColumn, 0
EDbWrongType, 1
EDbInUpdate, 2
EDbNotInUpdate, 3
EDbInvalidRow, 4
EDbRowNotRead, 5
EDbReadOnly, 6
EDbTableOpen, 7
EDbNotEvaluated, 8
EDbStreamOpen, 9
EDbRowSetConstraintMismatch, 10
EDbBeginNestedTransaction, 11
EDbUpdatesPendingOnCommit, 12
EDbUpdatesPendingOnRollback, 13
EDbNoCurrentTransaction, 14
EDbStreamsPendingOnCommit, 15
EDbStreamsPendingOnRollback, 16
EDbInvalidBookmark 17
***********************************************/
/*************************************************************
*
* Database view
*
* The database code is based on the sample DBMS application that comes with
* the SDK (with HEAVY modifications :))
*
**************************************************************/
CSMan2DBView::CSMan2DBView(CConfig *cData) : CViewBase(cData)
{
}
TBool CSMan2DBView::ViewScreenModeCompatible(TInt aScreenMode)
{
return (aScreenMode == 0);
}
TVwsViewIdAndMessage CSMan2DBView::ViewScreenDeviceChangedL()
{
return TVwsViewIdAndMessage(TVwsViewId(KUidSMan2App, KUidFlipclosedView));
}
void CSMan2DBView::ViewDeactivated()
{
// Note: ViewActivated of the new view is called BEFORE ViewDeactivated of the old view.
// Therefore, we mustn't make any changes to the toolbar in our call to doCloseDB else it will
// overwrite any toolbar that has been set by the new view. Hence we call doCloseDB with
// EFalse
doCloseDB(EFalse);
activateCount--;
if (activateCount <= 0)
{
MakeVisible(EFalse);
static_cast<CEikAppUi*>(iEikonEnv->AppUi())->RemoveFromStack(this);
}
}
void CSMan2DBView::ViewActivatedL(const TVwsViewId& /*aPrevViewId*/, TUid /*aCustomMessageId*/, const TDesC8& /*aCustomMessage*/)
{
doViewActivated();
}
TVwsViewId CSMan2DBView::ViewId() const
{
return TVwsViewId(KUidSMan2App, KUidDBView);
}
CSMan2DBView::~CSMan2DBView()
{
DeInitDB();
delete fieldLabelsArray;
}
void CSMan2DBView::doChangePassword()
{
// Can't use the standard set password dialog because it doesn't expose the new password
// after it's done
if (!dbIsOpened)
InitDB();
if (dbIsOpened)
{
TPassword promptedPassword;
CSetPasswordDialog *passwordDialog = new (ELeave) CSetPasswordDialog(&promptedPassword);
if (passwordDialog->ExecuteLD(R_DIALOG_DB_CHANGEPASSWORD) == EEikBidOk)
{
// Only re-encrypt if passwords are different
if (promptedPassword.Compare(dbPassword) != 0)
{
// Old stuff for accessing the DB
CSecurityBase *oldSecurityBase = Security::NewL();
oldSecurityBase->SetL(TPtrC(), dbPassword);
TBuf8<KMaxPassword> password;
password.Copy(dbPassword);
// New stuff for re-encrypting the DB
CSecurityBase *newSecurityBase = Security::NewL();
newSecurityBase->SetL(TPtrC(), promptedPassword);
TBuf8<KMaxPassword> newPassword;
newPassword.Copy(promptedPassword);
CEikonEnv::Static()->BusyMsgL(R_TBUF_DB_MSG_ENCRYPTING);
if (dbStore.ChangeSecurity(oldSecurityBase->NewDecryptL(password), newSecurityBase->NewEncryptL(newPassword)) != KErrNone)
iEikonEnv->InfoMsg(R_TBUF_DB_ERR_CHANGEPASSWORD);
else
iEikonEnv->InfoMsg(R_TBUF_MISC_DONE);
CEikonEnv::Static()->BusyMsgCancel();
delete oldSecurityBase;
delete newSecurityBase;
}
}
}
else
iEikonEnv->InfoMsg(R_TBUF_DB_ERR_CHANGEPASSWORD);
}
// WARNING: This function deletes the entire database and reinitializes it!! For those times when
// you forgot your password. :(
void CSMan2DBView::doReInitDB()
{
HBufC* dataBuffer = CEikonEnv::Static()->AllocReadResourceL(R_TBUF_MISC_DELETE_TITLE);
HBufC* dataBuffer2 = CEikonEnv::Static()->AllocReadResourceL(R_TBUF_DB_CONFIRM_DELETE);
/*
TBuf<6> title;
TBuf<50> prompt;
CEikonEnv::Static()->ReadResource(title, R_TBUF_MISC_DELETE_TITLE);
CEikonEnv::Static()->ReadResource(prompt, R_TBUF_DB_CONFIRM_REINIT);
*/
if (CEikonEnv::Static()->QueryWinL(*dataBuffer, *dataBuffer2))
{
// Not really necessary but i'm just paranoid. :)
delete dataBuffer;
delete dataBuffer2;
if (dbIsOpened)
DeInitDB();
// Faster than the Destroy() member call
TInt retVal = EikFileUtils::DeleteFile(dbFileName);
if (retVal == KErrNone)
{
InitDB();
if (dbIsOpened)
{
DeInitDB();
iEikonEnv->InfoMsg(R_TBUF_MISC_DONE);
}
HideAllControls();
}
else if (retVal != KErrNotFound)
iEikonEnv->InfoMsg(R_TBUF_DB_ERR_REINIT);
else
iEikonEnv->InfoMsg(R_TBUF_DB_ERR_NODB);
}
else
{
delete dataBuffer;
delete dataBuffer2;
}
}
TBool CSMan2DBView::doLongDBOp(TInt stepNumber)
{
TInt baseStepNumber;
TInt res = KErrNone;
TBool retVal = EFalse;
baseStepNumber = stepNumber;
CDBProgressDialog* progressDialog = new (ELeave) CDBProgressDialog;
progressDialog->ExecuteLD(R_DIALOG_DB_COMPRESS);
progressDialog->setProgressMaxValue(baseStepNumber);
progressDialog->DrawNow();
while ((stepNumber > 0) && (res == KErrNone))
{
res = incDB.Next(stepNumber);
progressDialog->updateProgress(baseStepNumber - stepNumber);
}
delete progressDialog;
if (res == KErrNone)
retVal = ETrue;
return retVal;
}
TBool CSMan2DBView::doCompact()
{
TInt retVal = EFalse;
if (!dbIsOpened)
InitDB();
if (dbIsOpened)
{
TInt stepNumber;
TInt res = incDB.Compact(dbStore, stepNumber);
if (res == KErrNone)
retVal = doLongDBOp(stepNumber);
}
return retVal;
}
TBool CSMan2DBView::doUpdateStats()
{
TInt retVal = EFalse;
if (!dbIsOpened)
InitDB();
if (dbIsOpened)
{
TInt stepNumber;
TInt res = incDB.UpdateStats(dbStore, stepNumber);
if (res == KErrNone)
retVal = doLongDBOp(stepNumber);
}
return retVal;
}
TBool CSMan2DBView::doDelete()
{
TPtrC tempText, recordIndex;
TBool retVal = ETrue;
TLex converter;
TUint32 value = 0;
if (cIndexListBox->SelectionIndexes()->Count() < 1)
iEikonEnv->InfoMsg(R_TBUF_DB_ERR_NORECORDS);
else
{
CEikonEnv::Static()->BusyMsgL(R_TBUF_DB_MSG_DELETING);
for (int i = 0; i < cIndexListBox->SelectionIndexes()->Count(); i++)
{
tempText.Set(cIndexListBox->Model()->ItemText(cIndexListBox->SelectionIndexes()->At(i)));
TextUtils::ColumnText(recordIndex, 1, &tempText);
converter.Assign(recordIndex);
converter.Val(value, EDecimal);
if (!DeleteRecord(value))
retVal = EFalse;
}
CEikonEnv::Static()->BusyMsgCancel();
}
return retVal;
}
void CSMan2DBView::doDisplayOneRecord(TBool aIsReadOnly)
{
if (cIndexListBox->Model()->ItemTextArray()->MdcaCount() > 0)
{
// Extract the index number of the currently highlighted record
TPtrC entryIndex, entryRow;
TUint32 recordIndex = 0;
TLex converter;
entryRow.Set(cIndexListBox->Model()->ItemTextArray()->MdcaPoint(cIndexListBox->View()->CurrentItemIndex()));
TextUtils::ColumnText(entryIndex, 1, &entryRow);
converter.Assign(entryIndex);
converter.Val(recordIndex, EDecimal);
currentRecordIndexIsValid = ETrue;
if (!aIsReadOnly)
ShowRecordsSingle(recordIndex, EFalse);
else
ShowRecordsSingleReadOnly(recordIndex);
}
else
iEikonEnv->InfoMsg(R_TBUF_DB_ERR_NORECORDS);
}
void CSMan2DBView::MoveEditCursors(TCursorPosition::TMovementType aCursorDirection)
{
if (fieldDisplayName->IsFocused())
fieldDisplayName->MoveCursorL(aCursorDirection, EFalse);
else
{
for (int j = 0; j < NUM_DATA_FIELDS; j++)
{
if (fieldLabels[j]->IsFocused())
fieldLabels[j]->Edwin()->MoveCursorL(aCursorDirection, EFalse);
else if (fieldValues[j]->IsFocused())
fieldValues[j]->MoveCursorL(aCursorDirection, EFalse);
}
}
}
TKeyResponse CSMan2DBView::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
{
if (currentDBView == DBView_Single_Editable)
{
if (aType == EEventKey)
{
if (aKeyEvent.iCode == EQuartzKeyConfirm)
{
if (SaveRecord(currentRecordIndex))
ShowRecordsList(ETrue, ETrue);
else
iEikonEnv->InfoMsg(R_TBUF_DB_ERR_SAVE);
return EKeyWasConsumed;
}
else if (aKeyEvent.iCode == EQuartzKeyTwoWayDown)
MoveEditCursors(TCursorPosition::EFRight);
else if (aKeyEvent.iCode == EQuartzKeyTwoWayUp)
MoveEditCursors(TCursorPosition::EFLeft);
}
return scrollableContainer->OfferKeyEventL(aKeyEvent, aType);
}
else if (currentDBView == DBView_Single_ReadOnly)
{
if (aType == EEventKey)
{
if (aKeyEvent.iCode == EQuartzKeyTwoWayDown)
{
readOnlyDisplay->MoveDisplayL(TCursorPosition::EFLineDown);
readOnlyDisplay->UpdateScrollBarsL();
return EKeyWasConsumed;
}
else if (aKeyEvent.iCode == EQuartzKeyTwoWayUp)
{
readOnlyDisplay->MoveDisplayL(TCursorPosition::EFLineUp);
readOnlyDisplay->UpdateScrollBarsL();
return EKeyWasConsumed;
}
else if (aKeyEvent.iCode == EQuartzKeyConfirm)
{
ShowRecordsList(EFalse, ETrue);
return EKeyWasConsumed;
}
}
return readOnlyDisplay->OfferKeyEventL(aKeyEvent, aType);
}
else // should be DBView_List
{
if (cIndexListBox->Model()->NumberOfItems() > 0)
{
if (aType == EEventKey)
{
if (aKeyEvent.iCode == EQuartzKeyConfirm)
{
doDisplayOneRecord(ETrue);
return EKeyWasConsumed;
}
else if (aKeyEvent.iCode == EQuartzKeyTwoWayDown)
{
cIndexListBox->View()->MoveCursorL(CListBoxView::ECursorNextItem, CListBoxView::ENoSelection);
cIndexListBox->UpdateScrollBarsL();
return EKeyWasConsumed;
}
else if (aKeyEvent.iCode == EQuartzKeyTwoWayUp)
{
cIndexListBox->View()->MoveCursorL(CListBoxView::ECursorPreviousItem, CListBoxView::ENoSelection);
cIndexListBox->UpdateScrollBarsL();
return EKeyWasConsumed;
}
}
return cIndexListBox->OfferKeyEventL(aKeyEvent, aType);
}
}
return EKeyWasNotConsumed;
}
// The next two routines are only called by InitDB once the DB file is initialied. Therefore, we can safely
// assume the database is opened and healthy
void CSMan2DBView::doCreateTable()
{
// Create a table
_LIT(KSQLCreateData, "CREATE TABLE Databank (Index COUNTER, DisplayName VARCHAR(30), NameField1 VARCHAR(30), ContentField1 VARCHAR(50), NameField2 VARCHAR(30), ContentField2 VARCHAR(50), NameField3 VARCHAR(30), ContentField3 VARCHAR(50), NameField4 VARCHAR(30), ContentField4 VARCHAR(50), NameField5 VARCHAR(30), ContentField5 VARCHAR(50))");
User::LeaveIfError(dbStore.Execute(KSQLCreateData));
_LIT(KSQLCreatePasswd, "CREATE TABLE Password (UserPassword VARCHAR(16))");
User::LeaveIfError(dbStore.Execute(KSQLCreatePasswd));
}
void CSMan2DBView::doCreateIndex()
{
_LIT(KSQLCreate1, "CREATE UNIQUE INDEX Index_Index ON Databank (Index)");
User::LeaveIfError(dbStore.Execute(KSQLCreate1));
_LIT(KSQLCreate2, "CREATE INDEX Index_DisplayName ON Databank (DisplayName)");
User::LeaveIfError(dbStore.Execute(KSQLCreate2));
}
TBool CSMan2DBView::DeleteRecord(TUint32 aIndex)
{
TBool retVal = EFalse;
TBuf<100> sqlString;
if (!dbIsOpened)
InitDB();
if (dbIsOpened)
{
sqlString.Format(_L("DELETE FROM Databank WHERE Index = %u"), aIndex);
if (dbStore.Execute(sqlString) < 0)
iEikonEnv->InfoMsg(R_TBUF_DB_ERR_DELETE);
else
retVal = ETrue;
}
else
iEikonEnv->InfoMsg(R_TBUF_DB_ERR_DELETE);
return retVal;
}
void CSMan2DBView::DeInitDB()
{
if (dbIsOpened)
{
dbView.Close();
dbStore.Close();
dbIsOpened = EFalse;
}
if (dbWindow)
{
delete dbWindow;
dbWindow = NULL;
}
if (fileStore)
{
delete fileStore;
fileStore = NULL;
}
if (securityBase)
{
delete securityBase;
securityBase = NULL;
}
currentRecordIndex = 0;
currentRecordIndexIsValid = EFalse;
dbPassword.Copy(DEFAULT_PASSWORD);
}
void CSMan2DBView::InitDB()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -