/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #include "CommandTextPopup.h" #include "Command.h" #include "GARChooserWindow.h" #include "Strings.h" #include #include #include "GARApplication.h" #include "ListIterator.h" #ifndef DXD_NON_UNIX_ENV_SEPARATOR #define SEP_CHAR ':' #else #define SEP_CHAR ';' #endif boolean CommandTextPopup::ClassInitialized = FALSE; String CommandTextPopup::DefaultResources[] = { NUL(char*) }; CommandTextPopup::CommandTextPopup (GARChooserWindow* chooser) : TextPopup ("fileCommand") { this->chooser = chooser; this->added_names = NUL(List*); this->file_timer = 0; this->lru_index = -1; this->dir_hist_size = 0; } CommandTextPopup::~CommandTextPopup() { if (this->added_names) delete this->added_names; if (this->file_timer) XtRemoveTimeOut (this->file_timer); } void CommandTextPopup::initialize() { } Widget CommandTextPopup::createTextPopup(Widget parent, const char **items, int nitems, SetTextCallback stc, ChangeTextCallback ctc, void *callData) { char help_msg[128]; int i, len; #define LENLIM 30 #define MAXITEMS 20 char *more_items[MAXITEMS]; const char *dxd = (char *)getenv("DXDATA"); if ((dxd) && (dxd[0])) { len = strlen(dxd); if (len > LENLIM) { char *tmpstr = DuplicateString (dxd); tmpstr[LENLIM] = '\0'; sprintf (help_msg, "The raw data file. (DXDATA in use: %s...)", tmpstr); delete tmpstr; } else sprintf (help_msg, "The raw data file. (DXDATA in use: %s)", dxd); } else { sprintf (help_msg, "The raw data file."); len = 0; } #undef LENLIM // // We'll always add uiroot/samples/data // int next = 0; if (len) { char *head = NUL(char*); char *top_head = NUL(char*); char *cp = top_head = DuplicateString(dxd); for (i=0; igetUIRoot(); if ((!uiroot) || (!uiroot[0])) uiroot = (char *)getenv("DXROOT"); if ((!uiroot) || (!uiroot[0])) uiroot = "/usr/lpp/dx"; char *sampDat = new char[strlen(uiroot) + strlen("samples/data") + 16]; if (uiroot[strlen(uiroot)-1] == '/') { sprintf (sampDat, "%s%s", uiroot, "samples/data"); } else { sprintf (sampDat, "%s/%s", uiroot, "samples/data"); } // // if DXROOT/samples/data isn't already in DXDATA, then we'll add it, too. // boolean duplicated = FALSE; for (i=0; ilru_index = next; Widget w = this->TextPopup::createTextPopup (parent, (const char **)more_items, next, stc, ctc, callData); this->added_names = new List; for (i=0; iadded_names->appendElement((void*)more_items[i]); this->setBubbleHelp (help_msg, this->textField); XmTextSource source = (XmTextSource)theGARApplication->getDataFileSource(); if (source) { XmTextSetSource (this->textField, source, 0, 0); } else { source = XmTextGetSource(this->textField); theGARApplication->setDataFileSource((void*)source); } this->addCallback(this->textField); return w; } void CommandTextPopup::activateTextCallback(const char *file_name, void *) { int i; char *cp; if (this->file_timer) XtRemoveTimeOut (this->file_timer); this->chooser->fileNameCB(); // // If the filename contained a directory add it to a short list displayed in the menu // if ((!file_name) || (!file_name[0])) return ; char *base_name = DuplicateString(file_name); int len = strlen(base_name); for (i=len-1; i>0; i--) { if (base_name[i] == '/') { base_name[i] = '\0'; break; } } if (i>1) { // // base_name contains a directory now // boolean match_found = FALSE; if (!this->added_names) this->added_names = new List; ListIterator it(*this->added_names); while (cp = (char *)it.getNext()) { if ((EqualString (cp, base_name)) || (EqualString(cp, file_name))) { match_found = TRUE; break; } } // // Don't let than the list get longer than... // // It's possible that the list is already longer than MAX_LIST_CNT // anyway, if DXDATA contained a huge number of paths. // #define MAX_LIST_CNT 15 if ((!match_found) && (this->added_names->getSize() <= MAX_LIST_CNT)) { // // If we're at the upper limit already, then get rid of one // string from the list and one widget from the menu. // if (this->added_names->getSize() == MAX_LIST_CNT) { Widget kid, *kids; int nkids; XtVaGetValues (this->popupMenu, XmNchildren, &kids, XmNnumChildren, &nkids, NULL); ASSERT (nkids == MAX_LIST_CNT); kid = kids[this->lru_index]; XtDestroyWidget (kid); char* trash = (char*)this->added_names->getElement(this->lru_index+1); this->added_names->deleteElement(this->lru_index+1); delete trash; } Widget button; button = XtVaCreateManagedWidget (base_name, xmPushButtonWidgetClass, this->popupMenu, NULL); XtAddCallback(button, XmNactivateCallback, (XtCallbackProc)TextPopup_ItemSelectCB, (XtPointer)this); this->added_names->appendElement ((void*)base_name); base_name = NUL(char*); } #undef MAX_LIST_CNT } if (base_name) delete base_name; } void CommandTextPopup::waitForFile () { if (this->file_timer) XtRemoveTimeOut (this->file_timer); this->file_timer = 0; if (this->chooser->getChoice()) this->file_timer = XtAppAddTimeOut (theApplication->getApplicationContext(), 500, (XtTimerCallbackProc)CommandTextPopup_FileTO, (XtPointer)this); } void CommandTextPopup::itemSelectCallback(const char *value) { this->chooser->setFileSearchDir(value); Command* cmd = this->chooser->getSelectDataCmd(); cmd->execute(); } void CommandTextPopup::addCallback (Widget t, XtCallbackProc cbp) { // // Set a timer to go off after the text is modified // XtAddCallback (t, XmNmodifyVerifyCallback, (XtCallbackProc) CommandTextPopup_ModifyCB, (XtPointer)this); if (cbp) XtAddCallback (this->textField, XmNmodifyVerifyCallback, cbp, (XtPointer)this); } extern "C" { void CommandTextPopup_ModifyCB (Widget , XtPointer clientData, XtPointer) { CommandTextPopup *ctp = (CommandTextPopup*)clientData; ASSERT(ctp); ctp->waitForFile(); } void CommandTextPopup_FileTO (XtPointer clientData, XtIntervalId* ) { CommandTextPopup* ctp = (CommandTextPopup*)clientData; ASSERT(ctp); ctp->file_timer = 0; ctp->chooser->fileNameCB(); } } // end extern C