--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commands/fed/src/fed.cpp Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,376 @@
+// fed.cpp
+//
+// Copyright (c) 2009 - 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+
+#include <e32cons.h>
+#include <BADESCA.H>
+#include <charconv.h>
+
+#include "fed.h"
+#include "viewbase.h"
+#include "bufferbase.h"
+#include "screenmngr.h"
+#include "cmdwindow.h"
+
+#include "filebuffer.h"
+#include "lrtextview.h"
+
+const TInt KDefScreenPosX = 0;
+const TInt KDefScreenPosY = 0;
+
+CFed* CFed::NewL(CColorConsoleBase& aConsole, RFs& aFs)
+ {
+ CFed* fed = new (ELeave) CFed(aConsole, aFs);
+ CleanupStack::PushL(fed);
+ fed->ConstructL();
+ CleanupStack::Pop(fed);
+ return fed;
+ }
+
+CFed* CFed::NewL(CConsoleBase& aConsole, RFs& aFs)
+ {
+ CFed* fed = new (ELeave) CFed(aConsole, aFs);
+ CleanupStack::PushL(fed);
+ fed->ConstructL();
+ CleanupStack::Pop(fed);
+ return fed;
+ }
+
+CFed::CFed(CColorConsoleBase& aConsole, RFs& aFs)
+ : CActive(CActive::EPriorityStandard), iFs(aFs), iConsole(aConsole), iColorConsole(&aConsole), iViewIdx(-1)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CFed::CFed(CConsoleBase& aConsole, RFs& aFs)
+ : CActive(CActive::EPriorityStandard), iFs(aFs), iConsole(aConsole), iViewIdx(-1)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CFed::~CFed()
+ {
+ Cancel();
+ for (TInt i = iViewArray.Count()-1; i >= 0; i--)
+ delete iViewArray[i];
+ iViewArray.Reset();
+ delete iCmdWindow;
+ delete iCharconv;
+ }
+
+void CFed::ConstructL()
+ {
+ iFs.CreatePrivatePath(EDriveC);
+ TSize size = iConsole.ScreenSize();
+ iScreenMngr.ResizeScreenL(TWindow(KDefScreenPosX, KDefScreenPosY, size.iWidth, size.iHeight));
+ if (iColorConsole)
+ {
+ iCmdWindow = CCommandWindow::NewL(iFs, *iColorConsole);
+ }
+ else
+ {
+ iCmdWindow = CCommandWindow::NewL(iFs, iConsole);
+ }
+ iCmdWindow->SetWindow(iScreenMngr.GetCommandWindow());
+
+ TRAPD(err, iCharconv = CCnvCharacterSetConverter::NewL());
+ if (!err)
+ {
+ // This can fail if charconv isn't properly configured in the ROM
+ ASSERT(iCharconv->PrepareToConvertToOrFromL(KCharacterSetIdentifierUtf8, iFs) == CCnvCharacterSetConverter::EAvailable);
+ }
+ }
+
+void CFed::StartL(CDesC16Array* aFiles)
+ {
+ CleanupStack::PushL(aFiles);
+ CreateViewsL(aFiles);
+ CleanupStack::PopAndDestroy(aFiles);
+
+ iConsole.Read(iStatus);
+ SetActive();
+ }
+
+//CActive
+void CFed::DoCancel()
+ {
+ iConsole.ReadCancel();
+ }
+
+void CFed::RunL()
+ {
+ if(iStatus.Int() < 0)
+ {
+ CActiveScheduler::Stop();
+ return;
+ }
+
+ TKeyCode code = iConsole.KeyCode();
+ TCmdType cmd = ProcessKeyL(code);
+
+ if(!ExecuteCommandL(cmd) && iViewIdx >= 0)
+ iViewArray[iViewIdx]->ConsumeKeyL(code);
+ if(iViewArray.Count() == 0)
+ {
+ // No more views, time to exit.
+ // Set the cursor to the bottom of the screen before we do - easier for the user to see that we've exited
+ TSize screenSize = iConsole.ScreenSize();
+ iConsole.SetPos(screenSize.iWidth-1, screenSize.iHeight-1); // Bottom right corner
+ iConsole.Write(_L(" ")); // This should cause the window to scroll and the cursor to be on the bottom line
+ CActiveScheduler::Stop();
+ return;
+ }
+
+ iConsole.Read(iStatus);
+ SetActive();
+ }
+
+TInt CFed::RunError(TInt aError)
+ {
+ if (iCmdWindow)
+ {
+ iCmdWindow->InfoPrint(_L("Leave occurred: %d"), aError);
+
+ // And rerequest further keys
+ iConsole.Read(iStatus);
+ SetActive();
+
+ return KErrNone;
+ }
+ return aError;
+ }
+
+void CFed::CreateViewsL(CDesC16Array* aFiles)
+ {
+ TInt n = aFiles->Count();
+ for (TInt i = 0; i < n; i++)
+ {
+ NewViewL((*aFiles)[i], ETrue);
+ }
+
+ if (n == 0)
+ {
+ // Create a new untitled view instead
+ NewViewL(KNullDesC);
+ }
+ if (iCharconv)
+ {
+ iCmdWindow->InfoPrint(_L("Welcome to fed. Press Ctrl-L for help."));
+ }
+ else
+ {
+ iCmdWindow->InfoPrint(_L("Warning: couldn't load charconv. UTF-8 not available."));
+ }
+ }
+
+CFed::TCmdType CFed::ProcessKeyL(const TKeyCode& aCode)
+ {
+ switch(aCode)
+ {
+ case CTRL('q'):
+ return ECmdCloseAll;
+ case EKeyF1:
+ case CTRL('l'):
+ return ECmdHelp;
+ case EKeyF2:
+ case CTRL('p'):
+ return ECmdPrevView;
+ case EKeyF3:
+ case CTRL('}'):
+ return ECmdNextView;
+ case EKeyEscape:
+ case CTRL('w'):
+ return ECmdCloseCurrent;
+ case CTRL('n'):
+ return ECmdNewDocument;
+ case CTRL('o'):
+ return ECmdOpenDocument;
+ case CTRL('r'):
+ case EKeyF5:
+ return ECmdRefresh;
+ default:
+ break;
+ }
+ return ECmdNone;
+ }
+
+TBool CFed::ExecuteCommandL(TCmdType aCmd)
+{
+ switch(aCmd)
+ {
+ case ECmdHelp:
+ ::ShowHelpL();
+ break;
+ case ECmdPrevView:
+ iViewIdx--;
+ if (iViewIdx < 0) iViewIdx = iViewArray.Count()-1;
+ iScreenMngr.AttachViewL(*iViewArray[iViewIdx]);
+ break;
+ case ECmdNextView:
+ iViewIdx++;
+ if (iViewIdx >= iViewArray.Count()) iViewIdx = 0;
+ iScreenMngr.AttachViewL(*iViewArray[iViewIdx]);
+ break;
+ case ECmdCloseCurrent:
+ CloseCurrentViewL();
+ break;
+ case ECmdCloseAll:
+ CloseAllViewsL();
+ break;
+ case ECmdNewDocument:
+ NewViewL(KNullDesC);
+ break;
+ case ECmdOpenDocument:
+ OpenDocumentL();
+ break;
+ case ECmdRefresh:
+ iScreenMngr.RefreshScreenL();
+ break;
+ default:
+ return EFalse;
+ }
+ return ETrue;
+}
+
+TBool CFed::CloseCurrentViewL()
+{
+ if(iViewIdx < 0)
+ {
+ //Show a message to the user that there is nothing to close
+ return EFalse;
+ }
+
+ CFedViewBase* view = iViewArray[iViewIdx];
+ TBool okToClose = ETrue;
+ if (view->Buffer().RefCount() == 1)
+ {
+ // We're the only view on this buffer - better ask about saving
+ okToClose = view->TryCloseL();
+ }
+
+ if (okToClose)
+ {
+ DeleteView();
+ }
+ return okToClose;
+ }
+
+void CFed::CloseAllViewsL()
+{
+ TBool ret = ETrue;
+ while(iViewIdx >=0 && ret)
+ ret = CloseCurrentViewL();
+}
+
+void CFed::DeleteView()
+ {
+ delete iViewArray[iViewIdx];
+ iViewArray.Remove(iViewIdx);
+ iScreenMngr.UnsetCurrentView();
+ if (iViewIdx >= iViewArray.Count())
+ {
+ iViewIdx = iViewArray.Count()-1;
+ }
+ if (iViewIdx >= 0)
+ {
+ // Attach the new frontmost view
+ iScreenMngr.AttachViewL(*(iViewArray[iViewIdx]));
+ }
+ }
+
+void CFed::NewViewL(const TDesC& aFileName, TBool aPromptOnNonexistantName)
+ {
+ CFileBuffer* buffer = NULL;
+ TRAPD(err, buffer = CFileBuffer::NewL(iFs, iCharconv, aFileName, EFalse));
+ if ((err == KErrNotFound || err == KErrPathNotFound) && aPromptOnNonexistantName)
+ {
+ if (iCmdWindow->Query(_L("File not found. Create? (yes/no) "), _L("yn")) == 'y')
+ {
+ buffer = CFileBuffer::NewL(iFs, iCharconv, aFileName, ETrue);
+ err = KErrNone;
+ }
+ }
+ User::LeaveIfError(err);
+
+ buffer->PushL();
+ CLRTextView* view = CLRTextView::NewL(*iCmdWindow, *buffer);
+ CleanupStack::Pop(buffer);
+ buffer->DecRef(); // view now has a ref to it
+ CleanupStack::PushL(view);
+ iViewArray.AppendL(view);
+ CleanupStack::Pop(view);
+ iViewIdx = iViewArray.Count()-1;
+ iScreenMngr.AddViewL(*view);
+ }
+
+void CFed::OpenDocumentL()
+ {
+ TFileName name;
+ TBool go = iCmdWindow->QueryFilename(_L("Open file: "), name);
+ if (go)
+ {
+ TInt prevIdx = iViewIdx;
+ TRAPD(err, NewViewL(name));
+ if (err)
+ {
+ switch (err)
+ {
+ case KErrNotFound:
+ iCmdWindow->InfoPrint(_L("File '%S' not found"), &name);
+ break;
+ case KErrPathNotFound:
+ iCmdWindow->InfoPrint(_L("KErrPathNotFound. Directory doesn't exist?"));
+ break;
+ case KErrBadName:
+ iCmdWindow->InfoPrint(_L("Bad name"));
+ break;
+ default:
+ iCmdWindow->InfoPrint(_L("Unable to open file: %d."), err);
+ break;
+ }
+ }
+ else if (!err && prevIdx >= 0)
+ {
+ CFedViewBase* prevView = iViewArray[prevIdx];
+ if (prevView->Buffer().Editable() && !prevView->Buffer().Modified() && prevView->Buffer().Title().Length() == 0)
+ {
+ // Then previous doc was an empty, untitled window, which this open should replace
+ delete prevView;
+ iViewArray.Remove(prevIdx);
+ iViewIdx = iViewArray.Count()-1;
+ }
+ }
+ }
+ }
+
+// Not usable: ^H = Bksp, ^M = CR, ^I = Tab, ^J = LF, ^Z = suspend, ^[ = Esc
+// Currently free: ^E, ^Y
+void CFed::ShowHelpL(HBufC* aHelpText)
+ {
+ _LIT(KHelpTitle, "Fed Help");
+ CleanupStack::PushL(aHelpText);
+ CConstDataBuffer* helpBuf = new(ELeave) CConstDataBuffer(KHelpTitle, aHelpText);
+ CleanupStack::Pop(aHelpText);
+ helpBuf->PushL();
+ CLRTextView* view = CLRTextView::NewL(*iCmdWindow, *helpBuf);
+ CleanupStack::Pop(helpBuf);
+ helpBuf->DecRef(); // view now has a ref to it
+ CleanupStack::PushL(view);
+ iViewArray.AppendL(view);
+ CleanupStack::Pop(view);
+ iViewIdx = iViewArray.Count()-1;
+ iScreenMngr.AddViewL(*view);
+ }
+
+void CFed::RedrawEverythingL()
+ {
+ ExecuteCommandL(ECmdRefresh);
+ }