Symbian/beginnings of Series 80 support
[p5sagit/p5-mst-13.2.git] / symbian / PerlApp.cpp
CommitLineData
27da23d5 1/* Copyright (c) 2004-2005 Nokia. All rights reserved. */
2
0added8b 3/* The PerlApp application is licensed under the same terms as Perl itself.
ed76c0e4 4 * Note that this PerlApp is for Symbian/Series 60/80 smartphones and it has
5 * nothing whatsoever to do with the ActiveState PerlApp. */
0added8b 6
27da23d5 7#include "PerlApp.h"
8
ed76c0e4 9#ifdef __SERIES60__
10# include <avkon.hrh>
11# include <aknnotewrappers.h>
12# include <AknCommonDialogs.h>
13# ifndef __SERIES60_1X__
14# include <CAknFileSelectionDialog.h>
15# endif
16#endif /* #ifdef __SERIES60__ */
17
18#ifdef __SERIES80__
19# include <eikon.hrh>
20# include <cknflash.h>
21# include <ckndgopn.h>
22#endif /* #ifdef __SERIES80__ */
23
27da23d5 24#include <apparc.h>
25#include <e32base.h>
26#include <e32cons.h>
27#include <eikenv.h>
28#include <bautils.h>
29#include <eikappui.h>
30#include <utf.h>
31#include <f32file.h>
32
27da23d5 33#include <coemain.h>
34
0added8b 35#ifndef PerlMin
36
27da23d5 37#include "PerlApp.hrh"
ed76c0e4 38
27da23d5 39#include "PerlApp.rsg"
40
f26f4a2f 41#endif //#ifndef PerlMin
0added8b 42
3c09d611 43#include "EXTERN.h"
e0f47ab0 44#include "perl.h"
27da23d5 45#include "PerlBase.h"
46
0added8b 47const TUid KPerlAppUid = {
48#ifdef PerlMinUid
49 PerlMinUid
50#else
51 0x102015F6
52#endif
53};
54
55_LIT(KDefaultScript, "default.pl");
27da23d5 56
57// This is like the Symbian _LIT() but without the embedded L prefix,
58// which enables using #defined constants (which need to carry their
59// own L prefix).
60#ifndef _LIT_NO_L
0added8b 61# define _LIT_NO_L(n, s) static const TLitC<sizeof(s)/2> n={sizeof(s)/2-1,s}
27da23d5 62#endif // #ifndef _LIT_NO_L
63
0added8b 64#ifdef PerlMinName
65_LIT_NO_L(KAppName, PerlMinName);
66#else
27da23d5 67_LIT(KAppName, "PerlApp");
0added8b 68#endif
69
70#ifndef PerlMin
f26f4a2f 71
27da23d5 72_LIT_NO_L(KFlavor, PERL_SYMBIANSDK_FLAVOR);
73_LIT(KAboutFormat,
74 "Perl %d.%d.%d, Symbian port %d.%d.%d, built for %S SDK %d.%d");
75_LIT(KCopyrightFormat,
76 "Copyright 1987-2005 Larry Wall and others, Symbian port Copyright Nokia 2004-2005");
77_LIT(KInboxPrefix, "\\System\\Mail\\");
78_LIT(KScriptPrefix, "\\Perl\\");
79
80_LIT8(KModulePrefix, SITELIB); // SITELIB from Perl config.h
81
82typedef TBuf<256> TMessageBuffer;
83typedef TBuf8<256> TPeekBuffer;
84typedef TBuf8<256> TFileName8;
85
f26f4a2f 86#endif // #ifndef PerlMin
87
27da23d5 88// Usage: DEBUG_PRINTF((_L("%S"), &aStr))
89#if 1
90#define DEBUG_PRINTF(s) {TMessageBuffer message; message.Format s; YesNoDialogL(message);}
91#endif
92
f26f4a2f 93static void DoRunScriptL(TFileName aScriptName);
94
27da23d5 95TUid CPerlAppApplication::AppDllUid() const
96{
97 return KPerlAppUid;
98}
99
100enum TPerlAppPanic
101{
102 EPerlAppCommandUnknown = 1
103};
104
105void Panic(TPerlAppPanic aReason)
106{
107 User::Panic(KAppName, aReason);
108}
109
110void CPerlAppUi::ConstructL()
111{
112 BaseConstructL();
113 iAppView = CPerlAppView::NewL(ClientRect());
114 AddToStackL(iAppView);
115 iFs = NULL;
116 CEikonEnv::Static()->DisableExitChecks(ETrue); // Symbian FAQ-0577.
117}
118
119CPerlAppUi::~CPerlAppUi()
120{
121 if (iAppView) {
122 iEikonEnv->RemoveFromStack(iAppView);
123 delete iAppView;
124 iAppView = NULL;
125 }
126 if (iFs) {
127 delete iFs;
128 iFs = NULL;
129 }
130 if (iDoorObserver) // Otherwise the embedding application waits forever.
131 iDoorObserver->NotifyExit(MApaEmbeddedDocObserver::EEmpty);
132}
133
0added8b 134#ifndef PerlMin
135
ed76c0e4 136#ifdef __SERIES60__
137
27da23d5 138static TBool DlgOk(CAknNoteDialog* dlg)
139{
140 return dlg && dlg->RunDlgLD() == EAknSoftkeyOk;
141}
142
ed76c0e4 143#endif /* #ifdef __SERIES60__ */
144
27da23d5 145static TBool OkCancelDialogL(TDesC& aMessage)
146{
ed76c0e4 147#ifdef __SERIES60__
27da23d5 148 CAknNoteDialog* dlg =
149 new (ELeave) CAknNoteDialog(CAknNoteDialog::EConfirmationTone);
150 dlg->PrepareLC(R_OK_CANCEL_DIALOG);
151 dlg->SetTextL(aMessage);
152 return DlgOk(dlg);
ed76c0e4 153#endif /* #ifdef __SERIES60__ */
154#ifdef __SERIES80__
155 return CCknFlashingDialog::RunDlgLD(_L("OK/Cancel"), aMessage, NULL,
156 CCknFlashingDialog::EShort,
157 NULL);
158#endif /* #ifdef __SERIES80__ */
27da23d5 159}
160
161static TBool YesNoDialogL(TDesC& aMessage)
162{
ed76c0e4 163#ifdef __SERIES60__
27da23d5 164 CAknNoteDialog* dlg =
165 new (ELeave) CAknNoteDialog(CAknNoteDialog::EConfirmationTone);
166 dlg->PrepareLC(R_YES_NO_DIALOG);
167 dlg->SetTextL(aMessage);
168 return DlgOk(dlg);
ed76c0e4 169#endif /* #ifdef __SERIES60__ */
170#ifdef __SERIES80__
171 return CCknFlashingDialog::RunDlgLD(_L("Yes/No"), aMessage, NULL,
172 CCknFlashingDialog::EShort,
173 NULL);
174#endif /* #ifdef __SERIES80__ */
27da23d5 175}
176
177static TInt InformationNoteL(TDesC& aMessage)
178{
ed76c0e4 179#ifdef __SERIES60__
27da23d5 180 CAknInformationNote* note = new (ELeave) CAknInformationNote;
181 return note->ExecuteLD(aMessage);
ed76c0e4 182#endif /* #ifdef __SERIES60__ */
183#ifdef __SERIES80__
184 return CCknFlashingDialog::RunDlgLD(_L("Info"), aMessage, NULL,
185 CCknFlashingDialog::ENormal,
186 NULL);
187#endif /* #ifdef __SERIES80__ */
27da23d5 188}
189
190static TInt ConfirmationNoteL(TDesC& aMessage)
191{
ed76c0e4 192#ifdef __SERIES60__
27da23d5 193 CAknConfirmationNote* note = new (ELeave) CAknConfirmationNote;
194 return note->ExecuteLD(aMessage);
ed76c0e4 195#endif /* #ifdef __SERIES60__ */
196#ifdef __SERIES80__
197 return CCknFlashingDialog::RunDlgLD(_L("Confirmation"), aMessage, NULL,
198 CCknFlashingDialog::ENormal,
199 NULL);
200#endif /* #ifdef __SERIES80__ */
27da23d5 201}
202
203static TInt WarningNoteL(TDesC& aMessage)
204{
ed76c0e4 205#ifdef __SERIES60__
27da23d5 206 CAknWarningNote* note = new (ELeave) CAknWarningNote;
207 return note->ExecuteLD(aMessage);
ed76c0e4 208#endif /* #ifdef __SERIES60__ */
209#ifdef __SERIES80__
210 CEikonEnv::Static()->AlertWin(aMessage);
211 return ETrue;
212#endif /* #ifdef __SERIES80__ */
27da23d5 213}
214
215static TInt TextQueryDialogL(const TDesC& aPrompt, TDes& aData, const TInt aMaxLength)
216{
ed76c0e4 217#ifdef __SERIES60__
27da23d5 218 CAknTextQueryDialog* dlg =
219 new (ELeave) CAknTextQueryDialog(aData);
220 dlg->SetPromptL(aPrompt);
221 dlg->SetMaxLength(aMaxLength);
222 return dlg->ExecuteLD(R_TEXT_QUERY_DIALOG);
ed76c0e4 223#endif /* #ifdef __SERIES60__ */
224#ifdef __SERIES80__
225 /* TODO */
226 return ETrue;
227#endif
27da23d5 228}
229
230// The isXXX() come from the Perl headers.
231#define FILENAME_IS_ABSOLUTE(n) \
232 (isALPHA(((n)[0])) && ((n)[1]) == ':' && ((n)[2]) == '\\')
233
234static TBool IsInPerl(TFileName aFileName)
235{
236 TInt offset = aFileName.FindF(KScriptPrefix);
237 return ((offset == 0 && // \foo
238 aFileName[0] == '\\')
239 ||
240 (offset == 2 && // x:\foo
241 FILENAME_IS_ABSOLUTE(aFileName)));
242}
243
244static TBool IsInInbox(TFileName aFileName)
245{
246 TInt offset = aFileName.FindF(KInboxPrefix);
247 return ((offset == 0 && // \foo
248 aFileName[0] == '\\')
249 ||
250 (offset == 2 && // x:\foo
251 FILENAME_IS_ABSOLUTE(aFileName)));
252}
253
254static TBool IsPerlModule(TParsePtrC aParsed)
255{
256 return aParsed.Ext().CompareF(_L(".pm")) == 0;
257}
258
259static TBool IsPerlScript(TParsePtrC aParsed)
260{
261 return aParsed.Ext().CompareF(_L(".pl")) == 0;
262}
263
264static void CopyFromInboxL(RFs aFs, const TFileName& aSrc, const TFileName& aDst)
265{
266 TBool proceed = ETrue;
267 TMessageBuffer message;
268
269 message.Format(_L("%S is untrusted. Install only if you trust provider."), &aDst);
270 if (OkCancelDialogL(message)) {
271 message.Format(_L("Install as %S?"), &aDst);
272 if (OkCancelDialogL(message)) {
273 if (BaflUtils::FileExists(aFs, aDst)) {
274 message.Format(_L("Replace old %S?"), &aDst);
275 if (!OkCancelDialogL(message))
276 proceed = EFalse;
277 }
278 if (proceed) {
279 // Create directory?
280 TInt err = BaflUtils::CopyFile(aFs, aSrc, aDst);
281 if (err == KErrNone) {
282 message.Format(_L("Installed %S"), &aDst);
283 ConfirmationNoteL(message);
284 }
285 else {
286 message.Format(_L("Failure %d installing %S"), err, &aDst);
287 WarningNoteL(message);
288 }
289 }
290 }
291 }
292}
293
294static TBool FindPerlPackageName(TPeekBuffer aPeekBuffer, TInt aOff, TFileName& aFn)
295{
296 aFn.SetMax();
297 TInt m = aFn.MaxLength();
298 TInt n = aPeekBuffer.Length();
299 TInt i = 0;
300 TInt j = aOff;
301
302 aFn.SetMax();
303 // The following is a little regular expression
304 // engine that matches Perl package names.
305 if (j < n && isSPACE(aPeekBuffer[j])) {
306 while (j < n && isSPACE(aPeekBuffer[j])) j++;
307 if (j < n && isALPHA(aPeekBuffer[j])) {
308 while (j < n && isALNUM(aPeekBuffer[j])) {
309 while (j < n &&
310 isALNUM(aPeekBuffer[j]) &&
311 i < m)
312 aFn[i++] = aPeekBuffer[j++];
313 if (j + 1 < n &&
314 aPeekBuffer[j ] == ':' &&
315 aPeekBuffer[j + 1] == ':' &&
316 i < m) {
317 aFn[i++] = '\\';
318 j += 2;
319 if (j < n &&
320 isALPHA(aPeekBuffer[j])) {
321 while (j < n &&
322 isALNUM(aPeekBuffer[j]) &&
323 i < m)
324 aFn[i++] = aPeekBuffer[j++];
325 }
326 }
327 }
328 while (j < n && isSPACE(aPeekBuffer[j])) j++;
329 if (j < n && aPeekBuffer[j] == ';' && i + 3 < m) {
330 aFn.SetLength(i);
331 aFn.Append(_L(".pm"));
332 return ETrue;
333 }
334 }
335 }
336 return EFalse;
337}
338
339static void GuessPerlModule(TFileName& aGuess, TPeekBuffer aPeekBuffer, TParse aDrive)
340{
341 TInt offset = aPeekBuffer.Find(_L8("package"));
342 if (offset != KErrNotFound) {
343 const TInt KPackageLen = 7;
344 TFileName q;
345
346 if (!FindPerlPackageName(aPeekBuffer, offset + KPackageLen, q))
347 return;
348
349 TFileName8 p;
350 p.Copy(aDrive.Drive());
351 p.Append(KModulePrefix);
352
353 aGuess.SetMax();
354 if (p.Length() + 1 + q.Length() < aGuess.MaxLength()) {
355 TInt i = 0, j;
356
357 for (j = 0; j < p.Length(); j++)
358 aGuess[i++] = p[j];
359 aGuess[i++] = '\\';
360 for (j = 0; j < q.Length(); j++)
361 aGuess[i++] = q[j];
362 aGuess.SetLength(i);
363 }
364 else
365 aGuess.SetLength(0);
366 }
367}
368
369static TBool LooksLikePerlL(TPeekBuffer aPeekBuffer)
370{
371 return aPeekBuffer.Left(2).Compare(_L8("#!")) == 0 &&
372 aPeekBuffer.Find(_L8("perl")) != KErrNotFound;
373}
374
375static TBool InstallStuffL(const TFileName &aSrc, TParse aDrive, TParse aFile, TPeekBuffer aPeekBuffer, RFs aFs)
376{
377 TFileName aDst;
378 TPtrC drive = aDrive.Drive();
379 TPtrC namext = aFile.NameAndExt();
380
381 aDst.Format(_L("%S%S%S"), &drive, &KScriptPrefix, &namext);
382 if (!IsPerlScript(aDst) && !LooksLikePerlL(aPeekBuffer)) {
383 aDst.SetLength(0);
384 if (IsPerlModule(aDst))
385 GuessPerlModule(aDst, aPeekBuffer, aDrive);
386 }
387 if (aDst.Length() > 0) {
388 CopyFromInboxL(aFs, aSrc, aDst);
389 return ETrue;
390 }
391
392 return EFalse;
393}
394
27da23d5 395static TBool RunStuffL(const TFileName& aScriptName, TPeekBuffer aPeekBuffer)
396{
397 TBool isModule = EFalse;
398
399 if (IsInPerl(aScriptName) &&
400 (IsPerlScript(aScriptName) ||
401 (isModule = IsPerlModule(aScriptName)) ||
402 LooksLikePerlL(aPeekBuffer))) {
403 TMessageBuffer message;
404
405 if (isModule)
406 message.Format(_L("Really run module %S?"), &aScriptName);
407 else
408 message.Format(_L("Run %S?"), &aScriptName);
409 if (YesNoDialogL(message))
410 DoRunScriptL(aScriptName);
411
412 return ETrue;
413 }
414
415 return EFalse;
416}
417
418void CPerlAppUi::InstallOrRunL(const TFileName& aFileName)
419{
420 TParse aFile;
421 TParse aDrive;
422 TMessageBuffer message;
423
424 aFile.Set(aFileName, NULL, NULL);
425 if (FILENAME_IS_ABSOLUTE(aFileName)) {
426 aDrive.Set(aFileName, NULL, NULL);
427 } else {
428 TFileName appName =
429 CEikonEnv::Static()->EikAppUi()->Application()->AppFullName();
430 aDrive.Set(appName, NULL, NULL);
431 }
432 if (!iFs)
433 iFs = &CEikonEnv::Static()->FsSession();
434 RFile f;
435 TInt err = f.Open(*iFs, aFileName, EFileRead);
436 if (err == KErrNone) {
437 TPeekBuffer aPeekBuffer;
438 err = f.Read(aPeekBuffer);
439 f.Close(); // Release quickly.
440 if (err == KErrNone) {
441 if (!(IsInInbox(aFileName) ?
442 InstallStuffL(aFileName, aDrive, aFile, aPeekBuffer, *iFs) :
443 RunStuffL(aFileName, aPeekBuffer))) {
444 message.Format(_L("Failed for file %S"), &aFileName);
445 WarningNoteL(message);
446 }
447 } else {
448 message.Format(_L("Error %d reading %S"), err, &aFileName);
449 WarningNoteL(message);
450 }
451 } else {
452 message.Format(_L("Error %d opening %S"), err, &aFileName);
453 WarningNoteL(message);
454 }
455 if (iDoorObserver)
456 delete CEikonEnv::Static()->EikAppUi();
457 else
458 Exit();
459}
460
0added8b 461#endif // #ifndef PerlMin
462
463static void DoRunScriptL(TFileName aScriptName)
464{
465 CPerlBase* perl = CPerlBase::NewInterpreterLC();
466 TRAPD(error, perl->RunScriptL(aScriptName));
467#ifndef PerlMin
468 if (error != KErrNone) {
469 TMessageBuffer message;
470 message.Format(_L("Error %d"), error);
471 YesNoDialogL(message);
472 }
f26f4a2f 473#endif // #ifndef PerlMin
0added8b 474 CleanupStack::PopAndDestroy(perl);
475}
476
f26f4a2f 477#ifndef PerlMin
478
27da23d5 479void CPerlAppUi::OpenFileL(const TDesC& aFileName)
480{
481 InstallOrRunL(aFileName);
482 return;
483}
484
f26f4a2f 485#endif // #ifndef PerlMin
486
27da23d5 487TBool CPerlAppUi::ProcessCommandParametersL(TApaCommand aCommand, TFileName& /* aDocumentName */, const TDesC8& /* aTail */)
488{
0added8b 489 if (aCommand == EApaCommandRun) {
490 TFileName appName = Application()->AppFullName();
ed76c0e4 491 TParse p;
492 p.Set(KDefaultScript, &appName, NULL);
493 TEntry aEntry;
494 RFs aFs;
495 aFs.Connect();
496 if (aFs.Entry(p.FullName(), aEntry) == KErrNone) {
497 DoRunScriptL(p.FullName());
498 Exit();
499 }
0added8b 500 }
27da23d5 501 return aCommand == EApaCommandOpen ? ETrue : EFalse;
502}
503
f26f4a2f 504#ifndef PerlMin
505
27da23d5 506void CPerlAppUi::SetFs(const RFs& aFs)
507{
508 iFs = (RFs*) &aFs;
509}
510
f26f4a2f 511#endif // #ifndef PerlMin
512
ed76c0e4 513static void DoHandleCommandL(TInt aCommand) {
0added8b 514#ifndef PerlMin
27da23d5 515 TMessageBuffer message;
0added8b 516#endif // #ifndef PerlMin
27da23d5 517
518 switch(aCommand)
519 {
0added8b 520#ifndef PerlMin
27da23d5 521 case EPerlAppCommandAbout:
522 {
523 message.Format(KAboutFormat,
524 PERL_REVISION,
525 PERL_VERSION,
526 PERL_SUBVERSION,
527 PERL_SYMBIANPORT_MAJOR,
528 PERL_SYMBIANPORT_MINOR,
529 PERL_SYMBIANPORT_PATCH,
530 &KFlavor,
531 PERL_SYMBIANSDK_MAJOR,
532 PERL_SYMBIANSDK_MINOR
533 );
534 InformationNoteL(message);
535 }
536 break;
537 case EPerlAppCommandTime:
538 {
539 CPerlBase* perl = CPerlBase::NewInterpreterLC();
540 const char *const argv[] =
541 { "perl", "-le",
542 "print 'Running in ', $^O, \"\\n\", scalar localtime" };
543 perl->ParseAndRun(sizeof(argv)/sizeof(char*), (char **)argv, 0);
544 CleanupStack::PopAndDestroy(perl);
545 }
546 break;
547 case EPerlAppCommandRunFile:
548 {
27da23d5 549 TFileName aScriptUtf16;
ed76c0e4 550#ifdef __SERIES60__
27da23d5 551 if (AknCommonDialogs::RunSelectDlgLD(aScriptUtf16,
552 R_MEMORY_SELECTION_DIALOG))
553 DoRunScriptL(aScriptUtf16);
ed76c0e4 554#endif /* #ifdef __SERIES60__ */
555#ifdef __SERIES80__
556 aScriptUtf16.Copy(_L("C:\\"));
557 if (CCknOpenFileDialog::RunDlgLD(aScriptUtf16,
558 CCknOpenFileDialog::EShowSystemFilesAndFolders |
559 CCknOpenFileDialog::EShowHiddenFilesAndFolders |
560 CCknOpenFileDialog::EShowAllDrives |
561 CCknOpenFileDialog::EShowExtendedView |
562 CCknOpenFileDialog::EShowNoFilesText) {
563 /* TODO: despite all the above flags still does not seem
564 * to allow navigating outside the default directory. */
565 TEntry aEntry;
566 RFs aFs;
567 aFs.Connect();
568 if (aFs.Entry(aScriptUtf16, aEntry) == KErrNone)
569 DoRunScriptL(aScriptUtf16);
570 /* else show error message? */
571 }
572#endif /* #ifdef __SERIES80__ */
573 }
27da23d5 574 break;
575 case EPerlAppCommandOneLiner:
576 {
577 _LIT(prompt, "Oneliner:");
ed76c0e4 578 CPerlAppUi* cAppUi =
579 STATIC_CAST(CPerlAppUi*, CEikonEnv::Static()->EikAppUi());
580 if (TextQueryDialogL(prompt,
581 cAppUi->iOneLiner,
582 KPerlAppOneLinerSize)) {
583 const TUint KPerlAppUtf8Multi = 3;
27da23d5 584 TBuf8<KPerlAppUtf8Multi * KPerlAppOneLinerSize> utf8;
585
ed76c0e4 586 CnvUtfConverter::ConvertFromUnicodeToUtf8(utf8, cAppUi->iOneLiner);
27da23d5 587 CPerlBase* perl = CPerlBase::NewInterpreterLC();
588 int argc = 3;
589 char **argv = (char**) malloc(argc * sizeof(char *));
590 User::LeaveIfNull(argv);
591
592 TCleanupItem argvCleanupItem = TCleanupItem(free, argv);
593 CleanupStack::PushL(argvCleanupItem);
594 argv[0] = (char *) "perl";
595 argv[1] = (char *) "-le";
596 argv[2] = (char *) utf8.PtrZ();
597 perl->ParseAndRun(argc, argv);
598 CleanupStack::PopAndDestroy(2, perl);
599 }
600 }
601 break;
602 case EPerlAppCommandCopyright:
603 {
604 message.Format(KCopyrightFormat);
605 InformationNoteL(message);
606 }
607 break;
ed76c0e4 608 case EPerlAppCommandAboutCopyright:
609 {
610 TMessageBuffer m1;
611 TMessageBuffer m2;
612 m1.Format(KAboutFormat,
613 PERL_REVISION,
614 PERL_VERSION,
615 PERL_SUBVERSION,
616 PERL_SYMBIANPORT_MAJOR,
617 PERL_SYMBIANPORT_MINOR,
618 PERL_SYMBIANPORT_PATCH,
619 &KFlavor,
620 PERL_SYMBIANSDK_MAJOR,
621 PERL_SYMBIANSDK_MINOR
622 );
623 InformationNoteL(message);
624 m2.Format(KCopyrightFormat);
625 message.Format(_L("%S %S"), &m1, &m2);
626 InformationNoteL(message);
627 }
628 break;
0added8b 629#endif // #ifndef PerlMin
27da23d5 630 default:
631 Panic(EPerlAppCommandUnknown);
ed76c0e4 632 }
633}
634
635#ifdef __SERIES60__
636
637void CPerlAppUi::HandleCommandL(TInt aCommand)
638{
639 switch(aCommand)
640 {
641 case EEikCmdExit:
642 case EAknSoftkeyExit:
643 Exit();
644 break;
645 default:
646 DoHandleCommandL(aCommand);
647 break;
648 }
649}
650
651#endif /* #ifdef __SERIES60__ */
652
653#ifdef __SERIES80__
654
655void CPerlAppView::HandleCommandL(TInt aCommand) {
656 DoHandleCommandL(aCommand);
657}
658
659void CPerlAppUi::HandleCommandL(TInt aCommand) {
660 switch(aCommand)
661 {
662 case EEikCmdExit:
663 Exit();
664 break;
665 default:
666 iAppView->HandleCommandL(aCommand);
27da23d5 667 break;
668 }
669}
670
ed76c0e4 671#endif /* #ifdef __SERIES80__ */
672
27da23d5 673CPerlAppView* CPerlAppView::NewL(const TRect& aRect)
674{
675 CPerlAppView* self = CPerlAppView::NewLC(aRect);
676 CleanupStack::Pop(self);
677 return self;
678}
679
680CPerlAppView* CPerlAppView::NewLC(const TRect& aRect)
681{
682 CPerlAppView* self = new (ELeave) CPerlAppView;
683 CleanupStack::PushL(self);
684 self->ConstructL(aRect);
685 return self;
686}
687
688void CPerlAppView::ConstructL(const TRect& aRect)
689{
690 CreateWindowL();
691 SetRect(aRect);
692 ActivateL();
693}
694
ed76c0e4 695CPerlAppView::~CPerlAppView()
696{
697}
698
27da23d5 699void CPerlAppView::Draw(const TRect& /*aRect*/) const
700{
701 CWindowGc& gc = SystemGc();
702 TRect rect = Rect();
703 gc.Clear(rect);
704}
705
706CApaDocument* CPerlAppApplication::CreateDocumentL()
707{
708 CPerlAppDocument* document = new (ELeave) CPerlAppDocument(*this);
709 return document;
710}
711
712CEikAppUi* CPerlAppDocument::CreateAppUiL()
713{
714 CPerlAppUi* appui = new (ELeave) CPerlAppUi();
715 return appui;
716}
717
f26f4a2f 718
719#ifndef PerlMin
720
ed76c0e4 721CFileStore* CPerlAppDocument::OpenFileL(TBool aDoOpen, const TDesC& aFileName, RFs& aFs)
27da23d5 722{
723 CPerlAppUi* appui =
724 STATIC_CAST(CPerlAppUi*, CEikonEnv::Static()->EikAppUi());
725 appui->SetFs(aFs);
ed76c0e4 726 if (aDoOpen)
727 appui->OpenFileL(aFileName);
27da23d5 728 return NULL;
729}
730
f26f4a2f 731#endif // #ifndef PerlMin
732
27da23d5 733EXPORT_C CApaApplication* NewApplication()
734{
735 return new CPerlAppApplication;
736}
737
738GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
739{
740 return KErrNone;
741}
742