commands/fed/src/fed.cpp
changeset 0 7f656887cf89
child 78 b3ffff030d5c
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // fed.cpp
       
     2 // 
       
     3 // Copyright (c) 2009 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include <e32cons.h>
       
    14 #include <BADESCA.H>
       
    15 #include <charconv.h>
       
    16 
       
    17 #include "fed.h"
       
    18 #include "viewbase.h"
       
    19 #include "bufferbase.h"
       
    20 #include "screenmngr.h"
       
    21 #include "cmdwindow.h"
       
    22 
       
    23 #include "filebuffer.h"
       
    24 #include "lrtextview.h"
       
    25 
       
    26 const TInt KDefScreenPosX = 0;
       
    27 const TInt KDefScreenPosY = 0;
       
    28 
       
    29 CFed* CFed::NewL(CColorConsoleBase& aConsole, RFs& aFs)
       
    30 	{
       
    31 	CFed* fed = new (ELeave) CFed(aConsole, aFs);
       
    32 	CleanupStack::PushL(fed);
       
    33 	fed->ConstructL();
       
    34 	CleanupStack::Pop(fed);
       
    35 	return fed;
       
    36 	}
       
    37 
       
    38 CFed* CFed::NewL(CConsoleBase& aConsole, RFs& aFs)
       
    39 	{
       
    40 	CFed* fed = new (ELeave) CFed(aConsole, aFs);
       
    41 	CleanupStack::PushL(fed);
       
    42 	fed->ConstructL();
       
    43 	CleanupStack::Pop(fed);
       
    44 	return fed;
       
    45 	}
       
    46 
       
    47 CFed::CFed(CColorConsoleBase& aConsole, RFs& aFs)
       
    48 	: CActive(CActive::EPriorityStandard), iFs(aFs), iConsole(aConsole), iColorConsole(&aConsole), iViewIdx(-1)
       
    49 	{
       
    50 	CActiveScheduler::Add(this);
       
    51 	}
       
    52 
       
    53 CFed::CFed(CConsoleBase& aConsole, RFs& aFs)
       
    54 	: CActive(CActive::EPriorityStandard), iFs(aFs), iConsole(aConsole), iViewIdx(-1)
       
    55 	{
       
    56 	CActiveScheduler::Add(this);
       
    57 	}
       
    58 
       
    59 CFed::~CFed()
       
    60 	{
       
    61 	Cancel();
       
    62 	for (TInt i = iViewArray.Count()-1; i >= 0; i--)
       
    63 		delete iViewArray[i];
       
    64 	iViewArray.Reset();
       
    65 	delete iCmdWindow;
       
    66 	delete iCharconv;
       
    67 	}
       
    68 
       
    69 void CFed::ConstructL()
       
    70 	{
       
    71 	iFs.CreatePrivatePath(EDriveC);
       
    72 	TSize size = iConsole.ScreenSize();
       
    73 	iScreenMngr.ResizeScreenL(TWindow(KDefScreenPosX, KDefScreenPosY, size.iWidth, size.iHeight));
       
    74 	if (iColorConsole)
       
    75 		{
       
    76 		iCmdWindow = CCommandWindow::NewL(iFs, *iColorConsole);
       
    77 		}
       
    78 	else
       
    79 		{
       
    80 		iCmdWindow = CCommandWindow::NewL(iFs, iConsole);
       
    81 		}
       
    82 	iCmdWindow->SetWindow(iScreenMngr.GetCommandWindow());
       
    83 	
       
    84 	TRAPD(err, iCharconv = CCnvCharacterSetConverter::NewL());
       
    85 	if (!err)
       
    86 		{
       
    87 		// This can fail if charconv isn't properly configured in the ROM
       
    88 		ASSERT(iCharconv->PrepareToConvertToOrFromL(KCharacterSetIdentifierUtf8, iFs) == CCnvCharacterSetConverter::EAvailable);
       
    89 		}
       
    90 	}
       
    91 
       
    92 void CFed::StartL(CDesC16Array* aFiles)
       
    93 	{
       
    94 	CleanupStack::PushL(aFiles);
       
    95 	CreateViewsL(aFiles);
       
    96 	CleanupStack::PopAndDestroy(aFiles);
       
    97 
       
    98 	iConsole.Read(iStatus);
       
    99 	SetActive();
       
   100 	}
       
   101 
       
   102 //CActive
       
   103 void CFed::DoCancel()
       
   104 	{
       
   105 	iConsole.ReadCancel();
       
   106 	}
       
   107 
       
   108 void CFed::RunL()
       
   109 	{
       
   110 	if(iStatus.Int() < 0)
       
   111 		{
       
   112 		CActiveScheduler::Stop();
       
   113 		return;
       
   114 		}
       
   115 
       
   116 	TKeyCode code = iConsole.KeyCode();
       
   117 	TCmdType cmd = ProcessKeyL(code);
       
   118 
       
   119 	if(!ExecuteCommandL(cmd) && iViewIdx >= 0)
       
   120 		iViewArray[iViewIdx]->ConsumeKeyL(code);
       
   121 	if(iViewArray.Count() == 0)
       
   122 		{
       
   123 		// No more views, time to exit.
       
   124 		// Set the cursor to the bottom of the screen before we do - easier for the user to see that we've exited
       
   125 		TSize screenSize = iConsole.ScreenSize();
       
   126 		iConsole.SetPos(screenSize.iWidth-1, screenSize.iHeight-1); // Bottom right corner
       
   127 		iConsole.Write(_L(" ")); // This should cause the window to scroll and the cursor to be on the bottom line
       
   128 		CActiveScheduler::Stop();
       
   129 		return;
       
   130 		}
       
   131 
       
   132 	iConsole.Read(iStatus);
       
   133 	SetActive();
       
   134 	}
       
   135 
       
   136 TInt CFed::RunError(TInt aError)
       
   137 	{
       
   138 	if (iCmdWindow)
       
   139 		{
       
   140 		iCmdWindow->InfoPrint(_L("Leave occurred: %d"), aError);
       
   141 
       
   142 		// And rerequest further keys
       
   143 		iConsole.Read(iStatus);
       
   144 		SetActive();
       
   145 
       
   146 		return KErrNone;
       
   147 		}
       
   148 	return aError;
       
   149 	}
       
   150 
       
   151 void CFed::CreateViewsL(CDesC16Array* aFiles)
       
   152 	{
       
   153 	TInt n = aFiles->Count();
       
   154 	for (TInt i = 0; i < n; i++)
       
   155 		{
       
   156 		NewViewL((*aFiles)[i], ETrue);
       
   157 		}
       
   158 
       
   159 	if (n == 0)
       
   160 		{
       
   161 		// Create a new untitled view instead
       
   162 		NewViewL(KNullDesC);
       
   163 		}
       
   164 	if (iCharconv)
       
   165 		{
       
   166 		iCmdWindow->InfoPrint(_L("Welcome to fed. Press Ctrl-L for help."));
       
   167 		}
       
   168 	else
       
   169 		{
       
   170 		iCmdWindow->InfoPrint(_L("Warning: couldn't load charconv. UTF-8 not available."));
       
   171 		}
       
   172 	}
       
   173 
       
   174 CFed::TCmdType CFed::ProcessKeyL(const TKeyCode& aCode)
       
   175 	{
       
   176 	switch(aCode)
       
   177 		{
       
   178 	case CTRL('q'):
       
   179 		return ECmdCloseAll;
       
   180 	case EKeyF1:
       
   181 	case CTRL('l'):
       
   182 		return ECmdHelp;
       
   183 	case EKeyF2:
       
   184 	case CTRL('p'):
       
   185 		return ECmdPrevView;
       
   186 	case EKeyF3:
       
   187 	case CTRL('}'):
       
   188 		return ECmdNextView;
       
   189 	case EKeyEscape:
       
   190 	case CTRL('w'):
       
   191 		return ECmdCloseCurrent;
       
   192 	case CTRL('n'):
       
   193 		return ECmdNewDocument;
       
   194 	case CTRL('o'):
       
   195 		return ECmdOpenDocument;
       
   196 	case CTRL('r'):
       
   197 	case EKeyF5:
       
   198 		return ECmdRefresh;
       
   199 	default:
       
   200 		break;
       
   201 		}
       
   202 	return ECmdNone;
       
   203 	}
       
   204 
       
   205 TBool CFed::ExecuteCommandL(TCmdType aCmd)
       
   206 {
       
   207 	switch(aCmd)
       
   208 		{
       
   209 		case ECmdHelp:
       
   210 			::ShowHelpL();
       
   211 			break;
       
   212 		case ECmdPrevView:
       
   213 			iViewIdx--;
       
   214 			if (iViewIdx < 0) iViewIdx = iViewArray.Count()-1;
       
   215 			iScreenMngr.AttachViewL(*iViewArray[iViewIdx]);
       
   216 			break;
       
   217 		case ECmdNextView:
       
   218 			iViewIdx++;
       
   219 			if (iViewIdx >= iViewArray.Count()) iViewIdx = 0;
       
   220 			iScreenMngr.AttachViewL(*iViewArray[iViewIdx]);
       
   221 			break;
       
   222 		case ECmdCloseCurrent:
       
   223 			CloseCurrentViewL();
       
   224 			break;
       
   225 		case ECmdCloseAll:
       
   226 			CloseAllViewsL();
       
   227 			break;
       
   228 		case ECmdNewDocument:
       
   229 			NewViewL(KNullDesC);
       
   230 			break;
       
   231 		case ECmdOpenDocument:
       
   232 			OpenDocumentL();
       
   233 			break;
       
   234 		case ECmdRefresh:
       
   235 			iScreenMngr.RefreshScreenL();
       
   236 			break;
       
   237 		default:
       
   238 			return EFalse;
       
   239 		}
       
   240 	return ETrue;
       
   241 }
       
   242 
       
   243 TBool CFed::CloseCurrentViewL()
       
   244 {
       
   245 	if(iViewIdx < 0)
       
   246 		{
       
   247 		//Show a message to the user that there is nothing to close
       
   248 		return EFalse;
       
   249 		}
       
   250 
       
   251 	CFedViewBase* view = iViewArray[iViewIdx];
       
   252 	TBool okToClose = ETrue; 
       
   253 	if (view->Buffer().RefCount() == 1)
       
   254 		{
       
   255 		// We're the only view on this buffer - better ask about saving
       
   256 		okToClose = view->TryCloseL();
       
   257 		}
       
   258 
       
   259 	if (okToClose)
       
   260 		{
       
   261 		DeleteView();
       
   262 		}
       
   263 	return okToClose;
       
   264 	}
       
   265 
       
   266 void CFed::CloseAllViewsL()
       
   267 {
       
   268 	TBool ret = ETrue;
       
   269 	while(iViewIdx >=0 && ret)
       
   270 		ret = CloseCurrentViewL();
       
   271 }
       
   272 
       
   273 void CFed::DeleteView()
       
   274 	{
       
   275 	delete iViewArray[iViewIdx];
       
   276 	iViewArray.Remove(iViewIdx);
       
   277 	iScreenMngr.UnsetCurrentView();
       
   278 	if (iViewIdx >= iViewArray.Count())
       
   279 		{
       
   280 		iViewIdx = iViewArray.Count()-1;
       
   281 		}
       
   282 	if (iViewIdx >= 0)
       
   283 		{
       
   284 		// Attach the new frontmost view
       
   285 		iScreenMngr.AttachViewL(*(iViewArray[iViewIdx]));
       
   286 		}
       
   287 	}
       
   288 
       
   289 void CFed::NewViewL(const TDesC& aFileName, TBool aPromptOnNonexistantName)
       
   290 	{
       
   291 	CFileBuffer* buffer = NULL;
       
   292 	TRAPD(err, buffer = CFileBuffer::NewL(iFs, iCharconv, aFileName, EFalse));
       
   293 	if ((err == KErrNotFound || err == KErrPathNotFound) && aPromptOnNonexistantName)
       
   294 		{
       
   295 		if (iCmdWindow->Query(_L("File not found. Create? (yes/no) "), _L("yn")) == 'y')
       
   296 			{
       
   297 			buffer = CFileBuffer::NewL(iFs, iCharconv, aFileName, ETrue);
       
   298 			err = KErrNone;
       
   299 			}
       
   300 		}
       
   301 	User::LeaveIfError(err);
       
   302 
       
   303 	buffer->PushL();
       
   304 	CLRTextView* view = CLRTextView::NewL(*iCmdWindow, *buffer);
       
   305 	CleanupStack::Pop(buffer);
       
   306 	buffer->DecRef(); // view now has a ref to it
       
   307 	CleanupStack::PushL(view);
       
   308 	iViewArray.AppendL(view);
       
   309 	CleanupStack::Pop(view);
       
   310 	iViewIdx = iViewArray.Count()-1;
       
   311 	iScreenMngr.AddViewL(*view);
       
   312 	}
       
   313 
       
   314 void CFed::OpenDocumentL()
       
   315 	{
       
   316 	TFileName name;
       
   317 	TBool go = iCmdWindow->QueryFilename(_L("Open file: "), name);
       
   318 	if (go)
       
   319 		{
       
   320 		TInt prevIdx = iViewIdx;
       
   321 		TRAPD(err, NewViewL(name));
       
   322 		if (err)
       
   323 			{
       
   324 			switch (err)
       
   325 				{
       
   326 				case KErrNotFound:
       
   327 					iCmdWindow->InfoPrint(_L("File '%S' not found"), &name);
       
   328 					break;
       
   329 				case KErrPathNotFound:
       
   330 					iCmdWindow->InfoPrint(_L("KErrPathNotFound. Directory doesn't exist?"));
       
   331 					break;
       
   332 				case KErrBadName:
       
   333 					iCmdWindow->InfoPrint(_L("Bad name"));
       
   334 					break;
       
   335 				default:
       
   336 					iCmdWindow->InfoPrint(_L("Unable to open file: %d."), err);
       
   337 					break;
       
   338 				}
       
   339 			}
       
   340 		else if (!err && prevIdx >= 0)
       
   341 			{
       
   342 			CFedViewBase* prevView = iViewArray[prevIdx];
       
   343 			if (prevView->Buffer().Editable() && !prevView->Buffer().Modified() && prevView->Buffer().Title().Length() == 0)
       
   344 				{
       
   345 				// Then previous doc was an empty, untitled window, which this open should replace
       
   346 				delete prevView;
       
   347 				iViewArray.Remove(prevIdx);
       
   348 				iViewIdx = iViewArray.Count()-1;
       
   349 				}
       
   350 			}
       
   351 		}
       
   352 	}
       
   353 
       
   354 // Not usable: ^H = Bksp, ^M = CR, ^I = Tab, ^J = LF, ^Z = suspend, ^[ = Esc
       
   355 // Currently free: ^E, ^Y
       
   356 void CFed::ShowHelpL(HBufC* aHelpText)
       
   357 	{
       
   358 	_LIT(KHelpTitle, "Fed Help");
       
   359 	CleanupStack::PushL(aHelpText);
       
   360 	CConstDataBuffer* helpBuf = new(ELeave) CConstDataBuffer(KHelpTitle, aHelpText);
       
   361 	CleanupStack::Pop(aHelpText);
       
   362 	helpBuf->PushL();
       
   363 	CLRTextView* view = CLRTextView::NewL(*iCmdWindow, *helpBuf);
       
   364 	CleanupStack::Pop(helpBuf);
       
   365 	helpBuf->DecRef(); // view now has a ref to it
       
   366 	CleanupStack::PushL(view);
       
   367 	iViewArray.AppendL(view);
       
   368 	CleanupStack::Pop(view);
       
   369 	iViewIdx = iViewArray.Count()-1;
       
   370 	iScreenMngr.AddViewL(*view);
       
   371 	}
       
   372 
       
   373 void CFed::RedrawEverythingL()
       
   374 	{
       
   375 	ExecuteCommandL(ECmdRefresh);
       
   376 	}