Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
15 user(s) are online (13 user(s) are browsing Forums)

Members: 0
Guests: 15

more...

Support us!

Headlines

 
  Register To Post  

texteditor.gadget and copy/paste
Home away from home
Home away from home


See User information
@all

I'm developing small tools using texteditor.gadget that require copying text to the clipboard and pasting from it.
Instead of clipboard.device, I'm using textclip.library, which works well for both copying to and retrieving from the clipboard.
However, I'm facing issues with texteditor.gadget. Here are the details:

1. Unmarking Text and Setting Cursor After Copy

After copying text to the clipboard, I want the selection to unmark and the cursor to move to the start of the previously marked text. My current approach, executed after ITextClip->WriteClipVector, is:

// Set cursor to selection start
IIntuition->SetGadgetAttrs((struct Gadget *)textEditorwindowNULL,
    
GA_TEXTEDITOR_CursorXstartx,
    
GA_TEXTEDITOR_CursorYstarty,
    
TAG_DONE);

// Activate the text editor
if (IIntuition->ActivateGadget((struct Gadget *)textEditorwindowNULL)) {
    
IDOS->Printf("Text editor activated successfully\n");
} else {
    
IDOS->Printf("Failed to activate text editor\n");
}

// Verify cursor position
ULONG newCursorX 0newCursorY 0;
IIntuition->GetAttr(GA_TEXTEDITOR_CursorXtextEditor, &newCursorX);
IIntuition->GetAttr(GA_TEXTEDITOR_CursorYtextEditor, &newCursorY);
IDOS->Printf("Cursor set to position (%lu, %lu), selection should be cleared\n"newCursorXnewCursorY);

// Refresh to clear selection visually
IIntuition->RefreshGadgets((struct Gadget *)textEditorwindowNULL);
} else {
    
IDOS->Printf("Failed to write to clipboard\n");
}



This works, but is there a simpler way to instruct texteditor.gadget to unmark and reposition the cursor?

2. Pasting from Clipboard

I'm stuck when pasting text from the clipboard into the texteditor window. I successfully read the clipboard buffer, but pasting fails. My code is:

IDOS->Printf("Pasting text: '%s', length: %lu\n"clipTexttextLen);

// Ensure window and gadget are active
IIntuition->ActivateWindow(window);
if (!
IIntuition->ActivateGadget((struct Gadget *)textEditorwindowNULL)) {
    
IDOS->Printf("Failed to activate text editor before paste\n");
    
ITextClip->DisposeClipVector(clipText);
    return;
}

// Attempt to insert text at cursor
struct GP_TEXTEDITOR_InsertText insertMsg = {
    .
MethodID GM_TEXTEDITOR_InsertText,
    .
GInfo NULL// GadgetInfo can be NULL
    
.text clipText,
    .
pos GV_TEXTEDITOR_InsertText_Cursor
};

if (
IIntuition->IDoMethodA(textEditor, (Msg)&insertMsg)) {
    
IDOS->Printf("Successfully pasted %lu bytes into text editor\n"textLen);

    
// Activate and refresh
    
if (IIntuition->ActivateGadget((struct Gadget *)textEditorwindowNULL)) {
        
IDOS->Printf("Text editor activated successfully after paste\n");
    } else {
        
IDOS->Printf("Failed to activate text editor after paste\n");
    }
    
IIntuition->RefreshGadgets((struct Gadget *)textEditorwindowNULL);
    
IIntuition->RefreshWindowFrame(window);
} else {
    
IDOS->Printf("Failed to paste text into text editor: possible error in context or method\n");
}

ITextClip->DisposeClipVector(clipText);


I consistently get "Failed to paste text..." with IDoMethodA. Switching to DoGadgetMethodA yields the same error, though the text appears visually. Any suggestions?
Dealt with by using GA_TEXTEDITOR_Contents instead of GM_TEXTEDITOR_InsertText (which is strange, shouldn't it work too?)

3. Reading Selected Text for Clipboard

Reading selected text to copy to the clipboard works, but the process feels cumbersome. My current logic is:

Get selection coordinates via GM_TEXTEDITOR_BlockInfo (startx, starty, stopx, stopy).
Export full text with GM_TEXTEDITOR_ExportText.
Split text into lines by counting \n and replacing with \0.
Calculate indices, adjust order if needed.
Compute length, allocate a buffer, copy the selected portion, and add \n between lines.
Copy to clipboard.
Is there a more efficient method?

Any help would be greatly appreciated. Thanks!


Edited by kas1e on 2025/5/20 10:41:35
Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: texteditor.gadget and copy/paste
Home away from home
Home away from home


See User information
Another set of questions:

1. How should a scrollbar be integrated with the texteditor.gadget to reflect its content changes? Are there system-provided methods to handle this automatically, or must I manually calculate and update the scrollbar's properties? For example, do I need to compute the number of lines, window dimensions, and adjust the scrollbar size and position accordingly? Is there a simpler, built-in mechanism to attach a scrollbar to the text editor and have it function seamlessly, without manual recalculations ?

2.Is there a straightforward way to ensure the editor window remains active (i.e., with the cursor visible and ready for typing) after actions such as resizing the window, moving the window, or clicking outside the texteditor.gadget but within the main window (excluding toolbar buttons)? Are there specific options or flags to achieve this, or must I manually handle each case by checking conditions and invoking "ActivateGadget((struct Gadget *)textEditor, window, NULL);" together with "RefreshGadgets((struct Gadget *)textEditor, window, NULL);" to restore focus to the text editor ?

Thanks !

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: texteditor.gadget and copy/paste
Not too shy to talk
Not too shy to talk


See User information
I think Camilla is the best person to ask and she only hangs out on discord and amiga.org and also the https://developer.amigaos3.net/ forum AFAIK

Go to top
Re: texteditor.gadget and copy/paste
Home away from home
Home away from home


See User information
@kas1e

Use The ARexx interface.

1 & 3

BOOL Copy(struct Gadget *editorgad)
{
 
    
struct GP_TEXTEDITOR_ARexxCmd gptac = {0}; 
    if(
editorgad_ptr )
    {
        
gptac.MethodID GM_TEXTEDITOR_ARexxCmd;
        
gptac.command = (STRPTR)"COPY";
        if(
DoGadgetMethodA(editorgad,Window,NULL,(Msg)&gptac))
        {
            return 
TRUE// Copy succeded 
        
}
    }
    return 
FALSE;
}


2

/* Paste from clipboard */

BOOL Paste(struct Gadget *editorgad_ptr)
{
    
struct GP_TEXTEDITOR_ARexxCmd gptac = {0}; 

    if(
editorgad_ptr)
    {
        
gptac.MethodID GM_TEXTEDITOR_ARexxCmd;
        
gptac.command = (STRPTR)"PASTE";
        if(
DoGadgetMethodA(editorgad_ptr,Window,NULL,(Msg)&gptac))
        {
            
SetFileModified();
            return 
TRUE// Paste succeded 
        
}
    }
    return 
FALSE;
}


Both these methods cleanly handle the GUI updates and need no extra libs like TextClip

Go to top
Re: texteditor.gadget and copy/paste
Home away from home
Home away from home


See User information
@kas1e

For scroller use GA_TextEdit_Prop_#? to get the top visible and total entries and use these to apply the equivalent SCROLLER attributes.

Go to top
Re: texteditor.gadget and copy/paste
Home away from home
Home away from home


See User information
@kas1e

Quote:

Is there a straightforward way to ensure the editor window remains active


Use a method like WMHI_INTUITICK to poll the Window->MouseX amd MouseY values then when the mouse id over the editgadget activate it with LayoutActivateGadget() (on OS4)

Check that another gadget is not active at the time by testing the toplevel layout

ie
if(!
((
struct Gadget *)layout) -> Activation GACT_ACTIVATEGADGET))
{
LayoutActivateGaget(layout,Window,editorgadget);
}


This stops you continuosly activateing the gadget and also stop it from steel foxus from another activated gadget just because the mouse moved over the editor,

Go to top
Re: texteditor.gadget and copy/paste
Home away from home
Home away from home


See User information
@Andy
Thanks a bunch ! It helps and clear code a lot. I do use WMHI_INTUITICK already for control ghosting/unghosting states, but with window active is still not that clear. We don't have LayoutActivateGadget, and LM_ACTIVATEGADGET (WM one instead) but you probably mean something like :

// Check if another gadget is active in the top-level layout
                            
struct Gadget *layoutGadget = (struct Gadget *)resizableLayout;
                            if (!(
layoutGadget->Activation GACT_ACTIVEGADGET))
                            {
                                
// Activate the text editor gadget using the layout
                                
IIntuition->IDoMethod(resizableLayoutWM_ACTIVATEGADGET,
                                    (
struct Gadget *)textEditorwindowNULL);
                            }


?

This one didn't work, but this one works:

// Check if mouse is over the text editor gadget
                        
if (mouseX >= editorLeft && mouseX <= editorRight &&
                            
mouseY >= editorTop && mouseY <= editorBottom)
                        {
                            
// Check if another gadget is active in the top-level layout
                            
struct Gadget *layoutGadget = (struct Gadget *)resizableLayout;
                            if (!(
layoutGadget->Activation GACT_ACTIVEGADGET))
                            {
                                
// Activate the text editor gadget directly
                                
IIntuition->ActivateGadget((struct Gadget *)textEditorwindowNULL);
                            }
                        }



Anyway, that help only when the mouse over the texteditor , but texteditor not start to be active not after resize of window (because mouse not over it), not after i simple drag window (while it still active), not when i click on the toolbar gadget (but not toolbar buttons), and not when i simple iconify/deiconify, etc. I need it to react like this : if window is active , then texteditor gadget is active and cursor stays.

Same goes to cut/copy/paste : after it texteditor not active if i use toolbar buttons or menu when mouse outside of text editor.

So, thank you for idea with WHMI_INTUITICK, i make it as i want by this:

case WMHI_ACTIVE:
                    
// Set flag when window becomes active
                    
windowActive TRUE;
                    break;

                case 
WMHI_INTUITICK:
                    
// Activate text editor if the window is active and no other gadget is active
                    
if (window && windowActive)
                    {
                        
// Check if another gadget is active in the top-level layout
                        
struct Gadget *layoutGadget = (struct Gadget *)resizableLayout;
                        if (!(
layoutGadget->Activation GACT_ACTIVEGADGET))
                        {
                            
// Activate the text editor gadget directly
                            
IIntuition->ActivateGadget((struct Gadget *)textEditorwindowNULL);
                        }
                    }
                    break;


Then it works as expected ! Yahoo !

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: texteditor.gadget and copy/paste
Home away from home
Home away from home


See User information
@kas1eQuote:
kas1e wrote:@Andy
Thanks a bunch ! It helps and clear code a lot. I do use WMHI_INTUITICK already for control ghosting/unghosting states, but with window active is still not that clear. We don't have LayoutActivateGadget, and LM_ACTIVATEGADGET (WM one instead) but you probably mean something like :


Er we do except that its ActivateLayoutGadget() but I the got OS dependency the wrong way round and you should indeed use the WM_ACTIVATEGADGET.
Quote:

// Check if another gadget is active in the top-level layout
                            
struct Gadget *layoutGadget = (struct Gadget *)resizableLayout;
                            if (!(
layoutGadget->Activation GACT_ACTIVEGADGET))
                            {
                                
// Activate the text editor gadget using the layout
                                
IIntuition->IDoMethod(resizableLayoutWM_ACTIVATEGADGET,
                                    (
struct Gadget *)textEditorwindowNULL);
                            }


?

This one didn't work, but this one works:

Well it wouldn't you just applied the WM_ACTIVATEGADGET to a layooutgadget, should be the window class object! Also the method structure takes just ME=ethodID and gadget so that should be:

IDoMethod(WindowObject,(struct Gadget *)textEditor);
Quote:


[quote]
// Check if mouse is over the text editor gadget
                        
if (mouseX >= editorLeft && mouseX editorTop && mouseY Activation GACT_ACTIVEGADGET))
                            {
                                
// Activate the text editor gadget directly
                                
IIntuition->ActivateGadget((struct Gadget *)textEditorwindowNULL);
                            }
                        }




You *should* use the WM_METHOD and not Activate gadget directly, as the active gadget in a window.class window is the layout not the any of it's children( the layout passes on events to the texteditor or whichever gadget it thinks is active)

If you do that then the texteditor should remain active after resizing the window.

Quote:

Anyway, that help only when the mouse over the texteditor , but texteditor not start to be active not after resize of window (because mouse not over it), not after i simple drag window (while it still active), not when i click on the toolbar gadget (but not toolbar buttons), and not when i simple iconify/deiconify, etc. I need it to react like this : if window is active , then texteditor gadget is active and cursor stays.

Same goes to cut/copy/paste : after it texteditor not active if i use toolbar buttons or menu when mouse outside of text editor.

So, thank you for idea with WHMI_INTUITICK, i make it as i want by this:

case WMHI_ACTIVE:
                    
// Set flag when window becomes active
                    
windowActive TRUE;
                    break;

                case 
WMHI_INTUITICK:
                    
// Activate text editor if the window is active and no other gadget is active
                    
if (window && windowActive)
                    {
                        
// Check if another gadget is active in the top-level layout
                        
struct Gadget *layoutGadget = (struct Gadget *)resizableLayout;
                        if (!(
layoutGadget->Activation GACT_ACTIVEGADGET))
                        {
                            
// Activate the text editor gadget directly
                            
IIntuition->ActivateGadget((struct Gadget *)textEditorwindowNULL);
                        }
                    }
                    break;


Then it works as expected ! Yahoo !

Go to top

  Register To Post

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2024 The XOOPS Project