JColorIndex JXPathInput::GetTextColor ( const JCharacter* path, const JCharacter* base, const JBoolean requireWrite, const JColormap* colormap ) { if (JStringEmpty(path)) { return colormap->GetBlackColor(); } JString fullPath; if ((!JIsRelativePath(path) || !JStringEmpty(base)) && JConvertToAbsolutePath(path, base, &fullPath) && JDirectoryReadable(fullPath) && JCanEnterDirectory(fullPath) && (!requireWrite || JDirectoryWritable(fullPath))) { return colormap->GetBlackColor(); } else { return colormap->GetRedColor(); } }
JColorIndex JXFileInput::GetTextColor ( const JCharacter* fileName, const JCharacter* basePath, const JBoolean requireRead, const JBoolean requireWrite, const JBoolean requireExec, const JColormap* colormap ) { if (JStringEmpty(fileName)) { return colormap->GetBlackColor(); } JString fullName; if ((!JIsRelativePath(fileName) || !JStringEmpty(basePath)) && JConvertToAbsolutePath(fileName, basePath, &fullName) && (!requireRead || JFileReadable(fullName)) && (!requireWrite || JFileWritable(fullName)) && (!requireExec || JFileExecutable(fullName))) { return colormap->GetBlackColor(); } else { return colormap->GetRedColor(); } }
JString JXGetNewDirDialog::GetNewDirName() const { JString dirName = GetString(); if (JIsRelativePath(dirName)) { dirName = JCombinePathAndName(itsBasePath, dirName); } return dirName; }
JBoolean JXFileInput::InputValid() { if (itsAllowInvalidFileFlag) { return kJTrue; } else if (!JXInputField::InputValid()) { return kJFalse; } const JString& text = GetText(); if (text.IsEmpty()) { return JNegate(IsRequired()); } JString fullName; const JCharacter* errID = NULL; if (JIsRelativePath(text) && !HasBasePath()) { errID = kNoRelPathID; RecalcAll(kJTrue); } else if (!JConvertToAbsolutePath(text, itsBasePath, &fullName) || !JFileExists(fullName)) { errID = kDoesNotExistID; } else if (itsRequireReadFlag && !JFileReadable(fullName)) { errID = kUnreadableID; } else if (itsRequireWriteFlag && !JFileWritable(fullName)) { errID = kUnwritableID; } else if (itsRequireExecFlag && !JFileExecutable(fullName)) { errID = kCannotExecID; } if (JStringEmpty(errID)) { return kJTrue; } else { (JGetUserNotification())->ReportError(JGetString(errID)); return kJFalse; } }
JString JXPathInput::GetTextForChoosePath() const { JString text = GetText(); if (text.IsEmpty() && HasBasePath()) { text = itsBasePath; } else if (!text.IsEmpty() && JIsRelativePath(text) && HasBasePath()) { text = JCombinePathAndName(itsBasePath, text); } return text; }
JBoolean JXPathInput::GetPath ( JString* path ) const { const JString& text = GetText(); return JI2B(!text.IsEmpty() && (!JIsRelativePath(text) || HasBasePath()) && JConvertToAbsolutePath(text, itsBasePath, path) && JDirectoryExists(*path) && JDirectoryReadable(*path) && JCanEnterDirectory(*path) && (!itsRequireWriteFlag || JDirectoryWritable(*path))); }
void JXPathHistoryMenu::SetBasePath ( const JCharacter* path ) { if (JStringEmpty(path)) { ClearBasePath(); } else { assert( !JIsRelativePath(path) ); itsBasePath = path; } }
JBoolean JXFileInput::GetFile ( JString* fullName ) const { const JString& text = GetText(); return JI2B(!text.IsEmpty() && (!JIsRelativePath(text) || HasBasePath()) && JConvertToAbsolutePath(text, itsBasePath, fullName) && JFileExists(*fullName) && (!itsRequireReadFlag || JFileReadable(*fullName)) && (!itsRequireWriteFlag || JFileWritable(*fullName)) && (!itsRequireExecFlag || JFileExecutable(*fullName))); }
void JXFileInput::SetBasePath ( const JCharacter* path ) { if (JStringEmpty(path)) { ClearBasePath(); } else { assert( !JIsRelativePath(path) ); itsBasePath = path; RecalcAll(kJTrue); } }
void CBFileNameDisplay::HandleUnfocusEvent() { JXFileInput::HandleUnfocusEvent(); JBoolean saved = kJFalse; JString fullName; if (itsUnfocusAction != kCancel && JExpandHomeDirShortcut(GetText(), &fullName)) { if (JIsRelativePath(fullName) && !(JGetChooseSaveFile())->SaveFile("Save file as:", "", fullName, &fullName)) { fullName.Clear(); } if (!fullName.IsEmpty() && !JSameDirEntry(fullName, itsOrigFile) && itsDoc->SaveInNewFile(fullName)) { saved = kJTrue; JBoolean onDisk; fullName = itsDoc->GetFullName(&onDisk); SetText(fullName); if (itsUnfocusAction == kRename) { CBCleanUpAfterRename(itsOrigFile, fullName); } } } if (!saved) { SetText(itsOrigFile); } UpdateDisplay(kJFalse); // take control of text style itsDragSource->ProvideDirectSave(NULL); }
JString JFileNameToURL ( const JCharacter* fileName ) { assert( !JIsRelativePath(fileName) ); JString host, file; if (!JTranslateLocalToRemote(fileName, &host, &file)) { host = JGetHostName(); file = fileName; } JString url("file://"); url += host; url += file; return url; }
JString JXFileInput::GetTextForChooseFile() const { JString text = GetText(); if (text.IsEmpty() && HasBasePath()) { text = itsBasePath; JAppendDirSeparator(&text); } if (text.EndsWith(ACE_DIRECTORY_SEPARATOR_STR)) { text.AppendCharacter('*'); } if (!text.IsEmpty() && JIsRelativePath(text) && HasBasePath()) { text = JCombinePathAndName(itsBasePath, text); } return text; }
JBoolean JGetTrueName ( const JCharacter* name, JString* trueName ) { trueName->Clear(); if (!JNameUsed(name)) { return kJFalse; } // check if it is a directory else if (JDirectoryExists(name)) { const JString currPath = JGetCurrentDirectory(); JError err = JChangeDirectory(name); if (!err.OK()) { return kJFalse; } *trueName = JGetCurrentDirectory(); err = JChangeDirectory(currPath); assert_ok( err ); return kJTrue; } // it is a file, socket, fifo, etc. else { JString origPath, fileName; JSplitPathAndName(name, &origPath, &fileName); // get true directory JString truePath; if (!JGetTrueName(origPath, &truePath)) { return kJFalse; } // resolve symbolic link JString target; if ((JGetSymbolicLinkTarget(name, &target)).OK()) { if (JIsRelativePath(target)) { target.Prepend(truePath); } return JGetTrueName(target, trueName); } else { *trueName = JCombinePathAndName(truePath, fileName); return kJTrue; } } }
JXApplication::JXApplication ( int* argc, char* argv[], const JCharacter* appSignature, const JCharacter** defaultStringData ) : JXDirector(NULL), itsIgnoreDisplayDeletedFlag(kJFalse), itsIgnoreTaskDeletedFlag(kJFalse), itsSignature(appSignature), itsRestartCmd(argv[0]) { // initialize object itsDisplayList = new JPtrArray<JXDisplay>(JPtrArrayT::kDeleteAll); assert( itsDisplayList != NULL ); itsCurrDisplayIndex = 1; itsIdleTaskStack = new IdleTaskStack(JPtrArrayT::kDeleteAll); assert( itsIdleTaskStack != NULL ); itsIdleTasks = new JPtrArray<JXIdleTask>(JPtrArrayT::kDeleteAll); assert( itsIdleTasks != NULL ); itsCurrentTime = 0; itsMaxSleepTime = 0; itsLastIdleTime = 0; itsLastIdleTaskTime = 0; itsWaitForChildCounter = 0; itsUrgentTasks = new JPtrArray<JXUrgentTask>(JPtrArrayT::kDeleteAll); assert( itsUrgentTasks != NULL ); itsHasBlockingWindowFlag = kJFalse; itsHadBlockingWindowFlag = kJFalse; itsRequestQuitFlag = kJFalse; // if no path info specified, assume it's on exec path if (JIsRelativePath(itsRestartCmd) && itsRestartCmd.Contains(ACE_DIRECTORY_SEPARATOR_STR)) { const JString pwd = JGetCurrentDirectory(); itsRestartCmd = JCombinePathAndName(pwd, itsRestartCmd); } // initialize global objects JXCreateGlobals(this, appSignature, defaultStringData); ListenTo(JThisProcess::Instance()); // for SIGTERM // create display -- requires JXGetApplication() to work JString displayName; ParseBaseOptions(argc, argv, &displayName); JXDisplay* display; if (!JXDisplay::Create(displayName, &display)) { cerr << argv[0]; if (displayName.IsEmpty()) { cerr << ": Can't open display '" << XDisplayName(NULL) << '\''; } else { cerr << ": Can't open display '" << displayName << '\''; } cerr << endl; JThisProcess::Exit(1); } // start the timer #ifndef WIN32 itimerval timerInfo; timerInfo.it_interval.tv_sec = kTimerStart; timerInfo.it_interval.tv_usec = 0; timerInfo.it_value.tv_sec = kTimerStart; timerInfo.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &timerInfo, NULL); #endif // idle task to quit if add directors deactivated JXQuitIfAllDeactTask* task = new JXQuitIfAllDeactTask; assert( task != NULL ); task->Start(); }
JBoolean JXPathInput::Complete ( JXInputField* te, const JCharacter* basePath, // can be NULL JDirInfo* completer, JXStringCompletionMenu** menu // constructed if NULL ) { // only complete if caret is at end of text JIndex caretIndex; if (!te->GetCaretLocation(&caretIndex) || caretIndex != te->GetTextLength()+1) { return kJFalse; } // catch empty path if (te->IsEmpty()) { const JString path = JGetRootDirectory(); te->Paste(path); return kJTrue; } // convert to absolute path JString fullName; if (!JExpandHomeDirShortcut(te->GetText(), &fullName)) { return kJFalse; } if (JIsRelativePath(fullName)) { if (JStringEmpty(basePath)) { return kJFalse; } fullName = JCombinePathAndName(basePath, fullName); } // if completing ~ rather than ~/ if (fullName.EndsWith(ACE_DIRECTORY_SEPARATOR_STR) && !(te->GetText()).EndsWith(ACE_DIRECTORY_SEPARATOR_STR)) { JStripTrailingDirSeparator(&fullName); } // get path and wildcard filter JString path, name; if (fullName.EndsWith(ACE_DIRECTORY_SEPARATOR_STR)) { path = fullName; name = "*"; } else { JSplitPathAndName(fullName, &path, &name); name.AppendCharacter('*'); } // build completion list if (!(completer->GoTo(path)).OK()) { return kJFalse; } completer->SetWildcardFilter(name, kJFalse, kJTrue); if (completer->IsEmpty()) { return kJFalse; } // check for characters common to all matches JString maxPrefix = jGetFullName(completer, 1); const JSize matchCount = completer->GetEntryCount(); JString entryName; for (JIndex i=2; i<=matchCount; i++) { entryName = jGetFullName(completer, i); const JSize matchLength = JCalcMatchLength(maxPrefix, entryName); const JSize prefixLength = maxPrefix.GetLength(); if (matchLength < prefixLength) { maxPrefix.RemoveSubstring(matchLength+1, prefixLength); } } // use the completion list if (matchCount > 0 && maxPrefix.GetLength() > fullName.GetLength()) { maxPrefix.RemoveSubstring(1, fullName.GetLength()); if (matchCount == 1 && (completer->GetEntry(1)).IsDirectory()) { JAppendDirSeparator(&maxPrefix); } te->Paste(maxPrefix); // so Undo removes completion if (*menu != NULL) { (**menu).ClearRequestCount(); } return kJTrue; } else if (matchCount > 1) { if (*menu == NULL) { *menu = new JXStringCompletionMenu(te, kJFalse); assert( *menu != NULL ); } else { (**menu).RemoveAllItems(); } for (JIndex i=1; i<=matchCount; i++) { entryName = jGetName(completer, i); (**menu).AddString(entryName); } (**menu).CompletionRequested(name.GetLength()-1); return kJTrue; } else { return kJFalse; } }
JString JGetClosestDirectory ( const JCharacter* origDirName, const JBoolean requireWrite, const JCharacter* basePath ) { assert( !JStringEmpty(origDirName) ); JString workingDir; if (!JStringEmpty(basePath)) { workingDir = basePath; JAppendDirSeparator(&workingDir); } else { workingDir = JGetCurrentDirectory(); } JString dirName = origDirName; JString homeDir; JSize homeLength; if (origDirName[0] == '~' && !JExpandHomeDirShortcut(origDirName, &dirName, &homeDir, &homeLength)) { return JGetRootDirectory(); } else if (JIsRelativePath(origDirName)) { dirName.Prepend(workingDir); } assert( !JIsRelativePath(dirName) ); JString newDir, junkName; while (!JDirectoryExists(dirName) || !JCanEnterDirectory(dirName) || !JDirectoryReadable(dirName) || (requireWrite && !JDirectoryWritable(dirName))) { JStripTrailingDirSeparator(&dirName); if (JIsRootDirectory(dirName)) { break; } JSplitPathAndName(dirName, &newDir, &junkName); dirName = newDir; } // convert back to partial path, if possible if (origDirName[0] == '~' && dirName.BeginsWith(homeDir)) { dirName.ReplaceSubstring(1, homeDir.GetLength(), origDirName, homeLength); } else if (JIsRelativePath(origDirName) && dirName.GetLength() > workingDir.GetLength() && dirName.BeginsWith(workingDir)) { dirName.RemoveSubstring(1, workingDir.GetLength()); } return dirName; }
void JXPathInput::AdjustStylesBeforeRecalc ( const JString& buffer, JRunArray<Font>* styles, JIndexRange* recalcRange, JIndexRange* redrawRange, const JBoolean deletion ) { const JColormap* colormap = GetColormap(); const JSize totalLength = buffer.GetLength(); JString fullPath = buffer; if ((JIsRelativePath(buffer) && !HasBasePath()) || !JExpandHomeDirShortcut(buffer, &fullPath)) { fullPath.Clear(); } // Last clause because if JConvertToAbsolutePath() succeeds, we don't // want to further modify fullName. else if (JIsRelativePath(buffer) && !JConvertToAbsolutePath(buffer, itsBasePath, &fullPath)) { if (HasBasePath()) { fullPath = JCombinePathAndName(itsBasePath, buffer); } else { fullPath.Clear(); } } JSize errLength; if (fullPath.IsEmpty()) { errLength = totalLength; } else { const JString closestDir = JGetClosestDirectory(fullPath, itsRequireWriteFlag); if (fullPath.BeginsWith(closestDir)) { errLength = fullPath.GetLength() - closestDir.GetLength(); } else { errLength = totalLength; } } if (errLength > 0 && buffer.EndsWith(kThisDirSuffix)) { errLength++; // trailing . is trimmed } Font f = styles->GetFirstElement(); styles->RemoveAll(); if (errLength >= totalLength) { f.style.color = colormap->GetRedColor(); styles->AppendElements(f, totalLength); } else { f.style.color = colormap->GetBlackColor(); styles->AppendElements(f, totalLength - errLength); if (errLength > 0) { f.style.color = colormap->GetRedColor(); styles->AppendElements(f, errLength); } } *redrawRange += JIndexRange(1, totalLength); }
JBoolean JXPathInput::InputValid() { if (itsAllowInvalidPathFlag) { return kJTrue; } else if (!JXInputField::InputValid()) { return kJFalse; } const JString& text = GetText(); if (text.IsEmpty()) // paranoia -- JXInputField should have reported { return !IsRequired(); } JString path; if (JIsRelativePath(text) && !HasBasePath()) { (JGetUserNotification())->ReportError(JGetString(kNoRelPathID)); RecalcAll(kJTrue); return kJFalse; } if (!JConvertToAbsolutePath(text, itsBasePath, &path)) { (JGetUserNotification())->ReportError(JGetString(kInvalidPathID)); RecalcAll(kJTrue); return kJFalse; } const JString currDir = JGetCurrentDirectory(); const JError err = JChangeDirectory(path); JChangeDirectory(currDir); if (err.OK()) { if (!JDirectoryReadable(path)) { (JGetUserNotification())->ReportError(JGetString(kUnreadableID)); RecalcAll(kJTrue); return kJFalse; } else if (itsRequireWriteFlag && !JDirectoryWritable(path)) { (JGetUserNotification())->ReportError(JGetString(kUnwritableID)); RecalcAll(kJTrue); return kJFalse; } else { return kJTrue; } } const JCharacter* errID; if (err == kJAccessDenied) { errID = kAccessDeniedID; } else if (err == kJBadPath) { errID = kBadPathID; } else if (err == kJComponentNotDirectory) { errID = kCompNotDirID; } else { errID = kInvalidDirID; } (JGetUserNotification())->ReportError(JGetString(errID)); RecalcAll(kJTrue); return kJFalse; }
JBoolean CBFileNameDisplay::InputValid() { const JString& text = GetText(); if (itsUnfocusAction == kCancel) { return kJTrue; } else if (text.IsEmpty()) { (JGetUserNotification())->ReportError(JGetString(kEmptyErrorID)); return kJFalse; } else if (text.EndsWith(ACE_DIRECTORY_SEPARATOR_STR)) { (JGetUserNotification())->ReportError(JGetString(kNoFileNameID)); return kJFalse; } else if (JIsRelativePath(text)) { return kJTrue; // open Choose File dialog } JString path, fullPath, name; JSplitPathAndName(text, &path, &name); if (!JExpandHomeDirShortcut(path, &fullPath)) { return kJFalse; } const JString fullName = JCombinePathAndName(fullPath, name); JBoolean onDisk; const JString origFullName = itsDoc->GetFullName(&onDisk); if (onDisk && JSameDirEntry(origFullName, fullName)) { itsUnfocusAction = kCancel; return kJTrue; } if (JFileExists(fullName)) { const JCharacter* map[] = { "f", text }; const JString msg = JGetString(kOKToReplaceID, map, sizeof(map)); if (!(JGetUserNotification())->AskUserNo(msg)) { return kJFalse; } } if (!JDirectoryExists(fullPath)) { const JError err = JCreateDirectory(fullPath); if (!err.OK()) { err.ReportIfError(); return kJFalse; } } else if (!JDirectoryWritable(fullPath)) { const JError err = JAccessDenied(fullPath); err.ReportIfError(); return kJFalse; } if (itsUnfocusAction == kRename) { const JError err = JRenameVCS(origFullName, fullName); err.ReportIfError(); return err.OK(); } else { return kJTrue; } }
JBoolean CBApp::FindFile ( const JCharacter* fileName, const JBoolean caseSensitive, JString* fullName ) const { JBoolean cancelled = kJFalse; const JBoolean relative = JIsRelativePath(fileName); if (!relative && JFileExists(fileName)) { *fullName = fileName; return kJTrue; } else if (relative) { CBDirInfoList searchPaths; CollectSearchPaths(&searchPaths); const JSize dirCount = searchPaths.GetElementCount(), sysCount = itsSystemIncludeDirs->GetElementCount(); JBoolean found = kJFalse; JLatentPG pg; JString msg = "Searching for \""; msg += fileName; msg += "\"..."; pg.FixedLengthProcessBeginning(dirCount+sysCount, msg, kJTrue, kJFalse); JString path, newName; for (JIndex i=1; i<=dirCount; i++) { const CBDirInfo info = searchPaths.GetElement(i); if (!info.recurse) { *fullName = JCombinePathAndName(*(info.path), fileName); if (JFileExists(*fullName)) { found = kJTrue; break; } } else if (JSearchSubdirs(*(info.path), fileName, kJTrue, caseSensitive, &path, &newName, NULL, &cancelled)) { *fullName = JCombinePathAndName(path, newName); found = kJTrue; break; } else if (cancelled) { break; } if (!pg.IncrementProgress()) { cancelled = kJTrue; break; } } if (!found && !cancelled) { // We have to search system paths last because these are always // last on the compiler search path. for (JIndex i=1; i<=sysCount; i++) { if (JSearchSubdirs(*itsSystemIncludeDirs->GetElement(i), fileName, kJTrue, caseSensitive, &path, &newName, NULL, &cancelled)) { *fullName = JCombinePathAndName(path, newName); found = kJTrue; break; } else if (cancelled) { break; } if (!pg.IncrementProgress()) { cancelled = kJTrue; break; } } } pg.ProcessFinished(); searchPaths.DeleteAll(); if (found) { return kJTrue; } } if (!cancelled) { JString msg = "Unable to find the file \""; msg += fileName; msg += "\"."; (JGetUserNotification())->ReportError(msg); } fullName->Clear(); return kJFalse; }