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