Exemple #1
0
/*
** Timer proc for flushing output buffers periodically when the process
** takes too long.
*/
static void flushTimeoutProc(XtPointer clientData, XtIntervalId *id)
{
    WindowInfo *window = (WindowInfo *)clientData;
    shellCmdInfo *cmdData = window->shellCmdData;
    textBuffer *buf = TextGetBuffer(cmdData->textW);
    int len;
    char *outText;
    
    /* shouldn't happen, but it would be bad if it did */
    if (cmdData->textW == NULL)
    	return;

    outText = coalesceOutput(&cmdData->outBufs, &len);
    if (len != 0) {
	if (BufSubstituteNullChars(outText, len, buf)) {
	    safeBufReplace(buf, &cmdData->leftPos, &cmdData->rightPos, outText);
	    TextSetCursorPos(cmdData->textW, cmdData->leftPos+strlen(outText));
	    cmdData->leftPos += len;
	    cmdData->rightPos = cmdData->leftPos;
	} else
	    fprintf(stderr, "NEdit: Too much binary data\n");
    }
    XtFree(outText);

    /* re-establish the timer proc (this routine) to continue processing */
    cmdData->flushTimeoutID = XtAppAddTimeOut(
    	    XtWidgetToApplicationContext(window->shell),
    	    OUTPUT_FLUSH_FREQ, flushTimeoutProc, clientData);
}
Exemple #2
0
void SelectNumberedLine(WindowInfo *window, int lineNum)
{
    int i, lineStart = 0, lineEnd;

    /* count lines to find the start and end positions for the selection */
    if (lineNum < 1)
    	lineNum = 1;
    lineEnd = -1;
    for (i=1; i<=lineNum && lineEnd<window->buffer->length; i++) {
    	lineStart = lineEnd + 1;
    	lineEnd = BufEndOfLine(window->buffer, lineStart);
    }
    
    /* highlight the line */
    if (i>lineNum) {
	/* Line was found */
	if (lineEnd < window->buffer->length) {
	    BufSelect(window->buffer, lineStart, lineEnd+1);
	} else { 
	    /* Don't select past the end of the buffer ! */
	    BufSelect(window->buffer, lineStart, window->buffer->length);
	}
    } else {
	/* Line was not found -> position the selection & cursor at the end 
	   without making a real selection and beep */
	lineStart = window->buffer->length;
	BufSelect(window->buffer, lineStart, lineStart);
	XBell(TheDisplay, 0);
    }     
    MakeSelectionVisible(window, window->lastFocus);
    TextSetCursorPos(window->lastFocus, lineStart);
}
Exemple #3
0
/*
** Search the help text.  If allSections is true, searches all of the help
** text, otherwise searches only in parentTopic.
*/
static void searchHelpText(Widget parent, int parentTopic,
        const char *searchFor, int allSections, int startPos, int startTopic)
{    
    int topic, beginMatch, endMatch;
    int found = False;
    char * helpText  = NULL;
    
    /* Search for the string */
    for (topic=startTopic; topic<NUM_TOPICS; topic++)
    {
        if (!allSections && topic != parentTopic)
            continue;
        helpText = stitch(parent, HelpText[topic], NULL);

        if (SearchString(helpText, searchFor, SEARCH_FORWARD, SEARCH_LITERAL,
                False, topic == startTopic ? startPos : 0, &beginMatch,
                &endMatch, NULL, NULL, GetPrefDelimiters()))
        {
            found = True;
            XtFree(helpText);
            break;
        }
        XtFree(helpText);
    }

    if (!found)
    {
        if (startPos != 0 || (allSections && startTopic != 0))
        {
            /* Wrap search */
            searchHelpText(parent, parentTopic, searchFor, allSections, 0, 0);
            return;
        }
        DialogF(DF_INF, parent, 1, "String Not Found", "String Not Found", "OK");
        return;
    }
    
    /* update navigation history */  
    if (parentTopic != topic)
    {
        navHistForw[parentTopic]= topic;
        navHistBack[topic]= parentTopic;
    }
    
    /* If the appropriate window is already up, bring it to the top, if not,
       make the parent window become this topic */
    changeTopicOrRaise(parentTopic, topic);
    BufSelect(TextGetBuffer(HelpTextPanes[topic]), beginMatch, endMatch);
    TextSetCursorPos(HelpTextPanes[topic], endMatch);
    
    /* Save the search information for search-again */
    strcpy(LastSearchString, searchFor);
    LastSearchTopic = topic;
    LastSearchPos = endMatch;
    LastSearchWasAllTopics = allSections;
}
Exemple #4
0
static void gotoCB(Widget widget, WindowInfo *window, Atom *sel,
    	Atom *type, char *value, int *length, int *format)
{
     /* two integers and some space in between */
    char lineText[(TYPE_INT_STR_SIZE(int) * 2) + 5];
    int rc, lineNum, column, position, curCol;
    
    /* skip if we can't get the selection data, or it's obviously not a number */
    if (*type == XT_CONVERT_FAIL || value == NULL) {
    	XBell(TheDisplay, 0);
	return;
    }
    if (((size_t) *length) > sizeof(lineText) - 1) {
    	XBell(TheDisplay, 0);
	XtFree(value);
	return;
    }
    /* should be of type text??? */
    if (*format != 8) {
    	fprintf(stderr, "NEdit: Can't handle non 8-bit text\n");
    	XBell(TheDisplay, 0);
	XtFree(value);
	return;
    }
    strncpy(lineText, value, sizeof(lineText));
    lineText[sizeof(lineText) - 1] = '\0';
    
    rc = StringToLineAndCol(lineText, &lineNum, &column);
    XtFree(value);
    if (rc == -1) {
    	XBell(TheDisplay, 0);
	return;
    }

    /* User specified column, but not line number */
    if ( lineNum == -1 ) {
        position = TextGetCursorPos(widget);
        if (TextPosToLineAndCol(widget, position, &lineNum, &curCol) == False) {
            XBell(TheDisplay, 0);
            return;
        }
    }
    /* User didn't specify a column */
    else if ( column == -1 ) {
        SelectNumberedLine(window, lineNum);
        return;
    }

    position = TextLineAndColToPos(widget, lineNum, column );
    if ( position == -1 ) {
        XBell(TheDisplay, 0);
        return;
    }
    TextSetCursorPos(widget, position);
}
Exemple #5
0
static int fonttool_aac_cb(void *data)
{
    fonttool_ui *ui = (fonttool_ui *) data;
    if (ui->cstext_parent != NULL) {
        char *s = TextGetString(ui->cstext);
        int pos = TextGetCursorPos(ui->cstext);
        TextSetString(ui->cstext_parent, s);
        TextSetCursorPos(ui->cstext_parent, pos);
        xfree(s);
    }
    
    return RETURN_SUCCESS;
}
Exemple #6
0
void GotoMark(WindowInfo *window, Widget w, char label, int extendSel)
{
    int index, oldStart, newStart, oldEnd, newEnd, cursorPos;
    selection *sel, *oldSel;
    
    /* look up the mark in the mark table */
    label = toupper(label);
    for (index=0; index<window->nMarks; index++) {
    	if (window->markTable[index].label == label)
   	    break;
    }
    if (index == window->nMarks) {
    	XBell(TheDisplay, 0);
    	return;
    }
    
    /* reselect marked the selection, and move the cursor to the marked pos */
    sel = &window->markTable[index].sel;
    oldSel = &window->buffer->primary;
    cursorPos = window->markTable[index].cursorPos;
    if (extendSel) {
	oldStart = oldSel->selected ? oldSel->start : TextGetCursorPos(w);
	oldEnd = oldSel->selected ? oldSel->end : TextGetCursorPos(w);
	newStart = sel->selected ? sel->start : cursorPos;
	newEnd = sel->selected ? sel->end : cursorPos;
	BufSelect(window->buffer, oldStart < newStart ? oldStart : newStart,
		oldEnd > newEnd ? oldEnd : newEnd);
    } else {
	if (sel->selected) {
    	    if (sel->rectangular)
    		BufRectSelect(window->buffer, sel->start, sel->end,
			sel->rectStart, sel->rectEnd);
    	    else
    		BufSelect(window->buffer, sel->start, sel->end);
	} else
    	    BufUnselect(window->buffer);
    }
    
    /* Move the window into a pleasing position relative to the selection
       or cursor.   MakeSelectionVisible is not great with multi-line
       selections, and here we will sometimes give it one.  And to set the
       cursor position without first using the less pleasing capability
       of the widget itself for bringing the cursor in to view, you have to
       first turn it off, set the position, then turn it back on. */
    XtVaSetValues(w, textNautoShowInsertPos, False, NULL);
    TextSetCursorPos(w, cursorPos);
    MakeSelectionVisible(window, window->lastFocus);
    XtVaSetValues(w, textNautoShowInsertPos, True, NULL);
}
Exemple #7
0
/*
** Find the text of a hyperlink from a clicked character position somewhere
** within the hyperlink text, and display the help that it links to.
*/
static void followHyperlink(int topic, int charPosition, int newWindow)
{
    textDisp *textD = ((TextWidget)HelpTextPanes[topic])->text.textD;
    char * link_text;
    int    link_topic;
    int    link_pos;
    int end        = charPosition;
    int begin      = charPosition;
    char whatStyle = BufGetCharacter(textD->styleBuffer, end);
    
    /*--------------------------------------------------
    * Locate beginning and ending of current text style.
    *--------------------------------------------------*/
    while (whatStyle == BufGetCharacter(textD->styleBuffer, ++end));
    while (whatStyle == BufGetCharacter(textD->styleBuffer, begin-1))  begin--;

    link_text = BufGetRange (textD->buffer, begin, end);
    
    if (is_known_link (link_text, &link_topic, &link_pos) ) 
    {
        if (HelpWindows[link_topic] != NULL)
        {
            RaiseShellWindow(HelpWindows[link_topic], True);
        } else
        {
            if (newWindow)
            {
                HelpWindows[link_topic] = createHelpPanel(link_topic);
            } else
            {
                changeWindowTopic(topic, link_topic);
            }
        }
        navHistBack[link_topic] = topic;
        navHistForw[topic] = link_topic;
        TextSetCursorPos(HelpTextPanes[link_topic], link_pos);
        adaptNavigationButtons(link_topic);
        adaptNavigationButtons(topic);
    }
    XtFree (link_text);
}
Exemple #8
0
/*
** Clean up after the execution of a shell command sub-process and present
** the output/errors to the user as requested in the initial issueCommand
** call.  If "terminatedOnError" is true, don't bother trying to read the
** output, just close the i/o descriptors, free the memory, and restore the
** user interface state.
*/
static void finishCmdExecution(WindowInfo *window, int terminatedOnError)
{
    shellCmdInfo *cmdData = window->shellCmdData;
    textBuffer *buf;
    int status, failure, errorReport, reselectStart, outTextLen, errTextLen;
    int resp, cancel = False, fromMacro = cmdData->fromMacro;
    char *outText, *errText = NULL;

    /* Cancel any pending i/o on the file descriptors */
    if (cmdData->stdoutInputID != 0)
    	XtRemoveInput(cmdData->stdoutInputID);
    if (cmdData->stdinInputID != 0)
    	XtRemoveInput(cmdData->stdinInputID);
    if (cmdData->stderrInputID != 0)
    	XtRemoveInput(cmdData->stderrInputID);

    /* Close any file descriptors remaining open */
    close(cmdData->stdoutFD);
    if (cmdData->flags & ERROR_DIALOGS)
    	close(cmdData->stderrFD);
    if (cmdData->inPtr != NULL)
    	close(cmdData->stdinFD);

    /* Free the provided input text */
    if (cmdData->input != NULL)
	XtFree(cmdData->input);
    
    /* Cancel pending timeouts */
    if (cmdData->flushTimeoutID != 0)
    	XtRemoveTimeOut(cmdData->flushTimeoutID);
    if (cmdData->bannerTimeoutID != 0)
    	XtRemoveTimeOut(cmdData->bannerTimeoutID);
    
    /* Clean up waiting-for-shell-command-to-complete mode */
    if (!cmdData->fromMacro) {
	EndWait(window->shell);
	SetSensitive(window, window->cancelShellItem, False);
	if (cmdData->bannerIsUp)
    	    ClearModeMessage(window);
    }
    
    /* If the process was killed or became inaccessable, give up */
    if (terminatedOnError) {
	freeBufList(&cmdData->outBufs);
	freeBufList(&cmdData->errBufs);
    	waitpid(cmdData->childPid, &status, 0);
	goto cmdDone;
    }

    /* Assemble the output from the process' stderr and stdout streams into
       null terminated strings, and free the buffer lists used to collect it */
    outText = coalesceOutput(&cmdData->outBufs, &outTextLen);
    if (cmdData->flags & ERROR_DIALOGS)
    	errText = coalesceOutput(&cmdData->errBufs, &errTextLen);

    /* Wait for the child process to complete and get its return status */
    waitpid(cmdData->childPid, &status, 0);
    
    /* Present error and stderr-information dialogs.  If a command returned
       error output, or if the process' exit status indicated failure,
       present the information to the user. */
    if (cmdData->flags & ERROR_DIALOGS)
    {
        failure = WIFEXITED(status) && WEXITSTATUS(status) != 0;
        errorReport = *errText != '\0';

        if (failure && errorReport)
        {
            removeTrailingNewlines(errText);
            truncateString(errText, DF_MAX_MSG_LENGTH);
            resp = DialogF(DF_WARN, window->shell, 2, "Warning", "%s", "Cancel",
                    "Proceed", errText);
            cancel = resp == 1;
        } else if (failure)
        {
            truncateString(outText, DF_MAX_MSG_LENGTH-70);
            resp = DialogF(DF_WARN, window->shell, 2, "Command Failure",
                    "Command reported failed exit status.\n"
                    "Output from command:\n%s", "Cancel", "Proceed", outText);
            cancel = resp == 1;
        } else if (errorReport)
        {
            removeTrailingNewlines(errText);
            truncateString(errText, DF_MAX_MSG_LENGTH);
            resp = DialogF(DF_INF, window->shell, 2, "Information", "%s",
                    "Proceed", "Cancel", errText);
            cancel = resp == 2;
        }

        XtFree(errText);
        if (cancel)
        {
            XtFree(outText);
            goto cmdDone;
        }
    }
    
    /* If output is to a dialog, present the dialog.  Otherwise insert the
       (remaining) output in the text widget as requested, and move the
       insert point to the end */
    if (cmdData->flags & OUTPUT_TO_DIALOG) {
    	removeTrailingNewlines(outText);
	if (*outText != '\0')
    	    createOutputDialog(window->shell, outText);
    } else if (cmdData->flags & OUTPUT_TO_STRING) {
    	ReturnShellCommandOutput(window,outText, WEXITSTATUS(status));
    } else {
	buf = TextGetBuffer(cmdData->textW);
	if (!BufSubstituteNullChars(outText, outTextLen, buf)) {
	    fprintf(stderr,"NEdit: Too much binary data in shell cmd output\n");
	    outText[0] = '\0';
	}
	if (cmdData->flags & REPLACE_SELECTION) {
	    reselectStart = buf->primary.rectangular ? -1 : buf->primary.start;
	    BufReplaceSelected(buf, outText);
	    TextSetCursorPos(cmdData->textW, buf->cursorPosHint);
	    if (reselectStart != -1)
	    	BufSelect(buf, reselectStart, reselectStart + strlen(outText));
	} else {
	    safeBufReplace(buf, &cmdData->leftPos, &cmdData->rightPos, outText);
	    TextSetCursorPos(cmdData->textW, cmdData->leftPos+strlen(outText));
	}
    }

    /* If the command requires the file to be reloaded afterward, reload it */
    if (cmdData->flags & RELOAD_FILE_AFTER)
    	RevertToSaved(window);

    /* Command is complete, free data structure and continue macro execution */
    XtFree(outText);
cmdDone:
    XtFree((char *)cmdData);
    window->shellCmdData = NULL;
    if (fromMacro)
    	ResumeMacroExecution(window);
}
Exemple #9
0
void create_fonttool(TextStructure *cstext_parent)
{
    static fonttool_ui *ui = NULL;
    
    if (ui == NULL) {
        ui = xmalloc(sizeof(fonttool_ui));
        memset(ui, 0, sizeof(fonttool_ui));
	
        ui->fonttool_panel = CreateDialog(app_shell, "Font tool");

        ui->font_select = CreateFontChoice(ui->fonttool_panel, "Font:");
        FormAddVChild(ui->fonttool_panel, ui->font_select->menu);
        
        ui->font_table = CreateTable("fontTable", ui->fonttool_panel,
                                     FONT_TOOL_ROWS, FONT_TOOL_COLS,
                                     8, 16);
        TableFontInit(ui->font_table);
        TableSetDefaultColWidth(ui->font_table, 2);
        TableSetDefaultColAlignment(ui->font_table, ALIGN_BEGINNING);
        TableUpdateVisibleRowsCols(ui->font_table);

        AddTableDrawCellCB(ui->font_table, DrawCB, ui);
        AddTableEnterCellCB(ui->font_table, EnterCB, ui);
        AddOptionChoiceCB(ui->font_select, update_fonttool_cb, ui);

        FormAddVChild(ui->fonttool_panel, ui->font_table);

        ui->cstext = CreateCSText(ui->fonttool_panel, "CString:");

        AddTextValidateCB(ui->cstext, EditStringCB, ui);
        
        ui->aac_buts = CreateAACDialog(ui->fonttool_panel,
            ui->cstext->form, fonttool_aac_cb, ui);

        FormFixateVChild(ui->cstext->form);
        
        update_fonttool_cb(NULL, 0, ui);
    }

    if (cstext_parent == ui->cstext) {
        /* avoid recursion */
        return;
    }
    
    ui->cstext_parent = cstext_parent;
    
    if (ui->cstext_parent == NULL) {
        TextSetString(ui->cstext, "");
        WidgetSetSensitive(ui->aac_buts[0], FALSE);
        WidgetSetSensitive(ui->aac_buts[1], FALSE);
    } else {
        char *s = TextGetString(ui->cstext_parent);
        int pos = TextGetCursorPos(ui->cstext_parent);
        TextSetString(ui->cstext, s);
        TextSetCursorPos(ui->cstext, pos);
        xfree(s);
        WidgetSetSensitive(ui->aac_buts[0], TRUE);
        WidgetSetSensitive(ui->aac_buts[1], TRUE);
    }
    
    DialogRaise(ui->fonttool_panel);
}