Hi!
I am trying to put together a program for Amiga OS4 using Reaction that I once had on my Palm PDA. It was called BeSafe and it used the RIJNDAEL encoding method to store "safe" passwords on the Palm so that only the proper password would allow access to the data.
I have set up a reaction interface with a few tabs, each holding it own custom listbrowser. Right now I am just populating the data with arrays of hard coded strings.
Here are my questions:
1) I want to add sort capability to one or more of the columns in my listbrowser. I set the attributes for the listbowser to enable sorting, but when the program comes up I do not get the listrowser "arrow" at the title box of the listbrowser. I noticed this was true of the reaction demo included with OS4 as well - the listbrowser sort demo. The arrow doesn't appear until you click on the title. Is there a way to show the sort arrow when the listbrowser appears instead of after you click on the title box for that column?
2) What do I need to do to make automatic sorting work in a listbrowser column? The example under the listbrowser directory in reaction examples uses a custom sort and I think I am missing the simple steps required to do the built in column sort. I can get the custom sort to work fine...but it seems like extra code I shouldn't need perhaps?
3) Is there a way to obtain a numeric identifier for the current tab you are in when you have multiple tabs such that the tab Id is 0 to n?
4) Unrelated to reaction - I want to compile and build this RIJNDAEL source code and make it link to my code: http://www.efgh.com/software/rijndael.htm
I broke the source file into its component pieces - encrypt.c, decrypt.c, rijndael.c and rijndael.h - but when I use GCC to compile any of the .c code files, I get errors because each file references the other .c file for different unctions. How do I make .o files to link together to my program using GCC?
Thanks ... I can provide some source code later if you wish.
Also, thanks for the reaction beginners guide! It is good but as with anything can use more detail for certain aspects.
You need to tell listbrowser which column you want it to sort by. You can do this with the LISTBROWSER_SortColumn tag.
Set LBCIA_Sortable, LBCIA_AutoSort and LBCIA_SortArrow to TRUE for the columns that you want to be autosortable.
This is code that I use in DiskImageGUI for autosortable columns:
Use -c option:
gcc -c -o file1.o file1.c
gcc -c -o file2.o file2.c
gcc -c -o file3.o file3.c
gcc -o final_exe file1.o file2.o file3.o
Preferably you should use a Makefile instead of typing in commands manually into the shell so that only .c files that have actually changed are recompiled and also so that you don't need to remember all the options you need to use to compile your program.
Great! Okay, I got the sorting working using the built in sort. I had forgotten to set the LBCIA_sortable when allocating my listbrowser columns.
Thanks!
Ah, okay. I thought I tried the way you show to figure out the current tab, I'll try it again.
Yes...I need to use a makefile...or put all the code inline in one .c file, which is messy.
Okay, another listbrowser question.
How can I traverse the listbrowser elements to retrieve the text in order to store it to a file?
Here's what I am doing right now....
I have populated a listbrowser node list using a hard coded string array. Now I want to pull the elements out to save to a file...
When I print text and columns1 I see " " and "0". What silly mistake am I making here?
Thanks!
You're retrieving data from the node's userdata field, not the actual node/column text - are you sure you really want that? Retrieving text from a multi-column listbrowser is done like this:
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
Hi Trixie,
Doh! You are right! I am looking at the wrong thing...no wonder I am getting the wrong answer! I'll put in the code to access the column data and give it a try.
Thanks!
My source can be found here: http://www.os4coding.net/source/162
Scott
Salass00,
I downloaded codebench and am quite impressed! It should take care of my having to include multiple source files and creating makefiles for me. Great program!
Oh, sometimes when I exit codebench I get an program ISI error.
Also, what do I need to do in codebench to get the debugger to work?
Here's another listbrowser question - how do I make listbrowser data editable? I have tried adding LISTBROWSER_ShowSelected and LISTBROWSER_Editable to my creation of the listbrowsers when I do a newOBJ on them...but it doesn;t seem to make any difference. When I click inside any of the data items, I am not able to edit them....the row highlights showing it is selected, but it does not allow me to edit it.
Is there some sort of LBCIA control I need to add?
Thanks!
@AmigaOneFan
Someone who's used CodeBench will have to answer this question for you. If you post in the CodeBench support forum on www.amigans.net you will probably have a higher chance to get a reply from the author.
I had to check AminetReadme source code to refresh my memory on this topic. In addition to setting LISTBROWSER_Editable to TRUE when creating the listbrowser you also need to set for every node that you create, for every column that you want to be editable the LBNCA_Editable tag to TRUE and LBNCA_MaxChars tag to the max amount of characters that you want the user to be able to enter. Also when you want to set or change a text in one of your editable column(s) you need to use LBNCA_CopyText (set to TRUE) so that the text you provide with LBNCA_Text is copied into the node's internal buffer.
F.e. to create a listbrowser node with three editable columns (30 characters each):
Salass00,
Great! That did the trick! Thank you so much, I couldn't find any examples or any details on how to do this simple thing. You say you found this off of Aminet???
@AmigaOneFan
No, I was referring to AminetReadme program for creating/editing Aminet readme files.
Ah, back to some programming fun!
I am able to obtain the current tab number 0 to n using your suggestion. But now I want to delete from the current tab whatever row is selected in that tabs listbrowser. (See my code example here: http://www.os4coding.net/source/162 ).
On line 925 of this code I have code that responds to the selection of the delete entry button. How do I determine which row of the current tab's listbrowser is selected? As I mentioned above, I can figure out which tab I am on using IIntuition->GetAttr(CLICKTAB_Current, clicktab_object, ¤t_tab);
Also, once I determine which row of the listbrowser to delete, what do I need to do to refresh the list and update the tab listbrowser display?
Thanks!
You mean remove the node from the listbrowser?
This also frees the node.
If you just want to remove it the code gets slightly longer:
Okay, (I say a year later!) I finally got around to trying this. When I use the code:
IIntuition->GetAttr(LISTBROWSER_SelectedNode, listbrowser, (TAG *)&node);
node always returns -1, which is I believe the default value.
Why am I not seeing the actual selected node, no matter which row I have selected in my listbrowser? Is there some other parameter that needs to be initialized?
Oh, when I try using LISTBROWSER_Selected (just for fun) instead I always get a result of 0, again the default value for that field.
Note that I am using my own listbrowser name from my code pointed to previously, not the actual text "listbrowser" as shown.
What am I missing now?
Thanks!
@AmigaOneFan
As LISTBROWSER_SelectedNode contains a pointer to struct Node, I'd say the default value would be NULL, not -1. Just guessing though.
I'm not sure how your (TAG *) typecast might influence the result of the call, I've never seen it used before. I always retrieve the selected node like this:
What do you mean by "I am not seeing the actual selected node"? Doesn't the node (row) become highlighted when you click on it?
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
@trixie
I think he has the return values mixed up because -1 is the return value of LISTBROWSER_Selected when no node is selected, for LISTBROWSER_SelectedNode the equivalent value is NULL.
Using Tag type may in some cases be more portable than using uint32 because uint32 will fail on a 64-bit system (in this case it doesn't really matter because the cast is there just so the compiler doesn't throw a warning). Even better would of course be if AmigaOS had a type similar to IPTR on AROS (IPTR on AROS is an unsigned integer type that is guaranteed to always be large enough to contain a pointer).
Maybe he has forgot to set LISTBROWSER_ShowSelected to TRUE?
Thanks for the info. I am setting LISTBROWSER_ShowSelect TRUE in my code here:
... for each listbrowser I create (one for each of four tabs). And yes, when I select an item in the list it is highlighted and I can edit it and save it.
But, when I try to identify which item is selected using LISTBROWSER_SelectedNode as shown in the code in one of the earlier posts, the value never changes no matter which item I select. It is always (IIRC) -1. I want to perform operations on the listbrowser data by identifying which tab and which item is selected - for example to delete an item from the list. But although I can identify the correct tab (thanks for your previous help on this) I never get anything valid as far as which node (or item) is selected.
I must be doing something dumb wrong here...but it is just not obvious to me.
Thanks for your help! Any more ideas?
@AmigaOneFan
If your code example is still valid you're creating eight listbrowsers in line 252, 274, 294, 314 and than again at 421, 434, 447, 460 but only using four variables to remember the objects OBJ(OBJ_LISTBROWSER[1234]).
My guess would be the first four are the one which are beeing displayed but you're testing the wrong one because you have overwritten the corresponding variables.
You are adding two parent level layouts to your window (line 375 and 412) and I think that you shouldn't do that.
@gazelle
Yes, you are absolutely right! I wonder how that cut and paste error crept into the code!
Okay, fixed.
Now I am getting something returned when I look at my listbrowser nodes. The uint32 I get showing my active node is not a number but a pointer to the node, correct?
Thanks!
If you GetAttr() from LISTBROWSER_SelectedNode then the returned uint32 is actually a pointer to the currently selected node. A pointer is actually an address in memory = a 32 bit integer number.
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
@trixie wrote...
"the returned uint32 is actually a pointer to the currently selected node"
Yes, as I guessed. Good. got my delete node working now for all possible entries in all tabs! Hurray!
Now on to the next problem. I want to add a node at the bottom of a listbrowser list. To do so, I have a function named AddNode(struct List *browserlist, int columns). So I should know which browserlist to add an entry to, and how many coulmns it will have so I can set it up.
For now, I am just attempting my columns size of 5. First, I detach the browserlist like this:
then I create a blank node to add to the tail of the list....like this:
So, it goes ahead and does this, but what happens is not what I expect. Instead of adding a new node to the tail of my browserlist, what happens is that my browserlist gets erased completely. I see this when I click to another tab and then back to the one which I have added this new node to. It is now empty (have to do this because I am not updating the display...yet).
My call to the function is:
and it does not show any error that it is not adding the node.
This is likely another dumb pointer issue. You would think I would see these by now! But I am not seeing what I have missed here.
Any ideas or help would be appreciated.
Thanks!
oops...double post!
You forgot to attach the list to the browser again.
@AmigaOneFan
You should set LISTBROWSER_Labels to -1 not NULL if you're just removing the list so that you can add some modifications to it, also you want to add the list back after doing your modifications using IIntuition->SetGadgetAttrs().
@AmigaOneFan
As Thomas says, make sure you attach the list back to the listbrowser. Use SetGadgetAttrs() if you want the browser display to get updated right away, otherwise you can use SetAttrs().
@salass00
The listbrowser autodoc says quite explicitly that the "detach value" is ~0 or NULL, not -1.
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
-1 is the same value as ~0 (in 2's complement which practically all sane systems use). I find it strange that you do not know this...
As you may or may not have noticed I've used ~0 in the example code above but using either should be ok as they produce the same value.
He is using tabs (a.k.a. pages) so actually he should use SetPageGadgetAttrs instead of SetGadgetAttrs. Otherwise strange things will happen if the list browser he is changing is not on the page which is currently displayed.
If his listbrowser is located in a page gadget then he should of course use SetPageGadgetAttrs(). I didn't look too closely at his code so I didn't notice it was located in a clicktab page.
Modified code:
@salass00
Okay, this did the trick....
Thanks! As for being careful about updating tabs that are not currently viewed, I will be adding code to ensure my listbrowser list and object are the ones based on the current tab.
Thanks!
That's not a safe solution. The only 100% safe solution is to use SetPageGadgetAttrs() providing the pointer to the page in question.
Pages