PrefsObject

This forum is for general developer support questions.

Re: PrefsObject

Postby jaokim » Sat Sep 19, 2015 6:48 pm

I don't have much application library knowledge, so I don't know which six types there are. But, if I'm allowed to elaborate, I'm thinking one might want to support more types in the future. Therefore I think that an attribute would be better suited... Although, on the other hand, we'd get a less "typed" and uncontrolled structure.
My thought was that one would perhaps want, as an application programmer, to store application specific "blobs", with some sort of XML CDATA thingie, especially wen porting software. I'm imagining that the ported program has its own binary format, which we then could save using minimal Amiga application specific code, but still take advantage of Amiga specific functionality.

Like I said, I don't have any deep insight in exactly what application library supports for the prefs objects, so I might be proposing unsuitable stuff.

But either way, I'd prefer a format where the data type is an attribute, and not a static tag.
User avatar
jaokim
Beta Tester
Beta Tester
 
Posts: 89
Joined: Sat Jun 18, 2011 1:41 am

Re: PrefsObject

Postby trixie » Sat Sep 19, 2015 7:06 pm

@jaokim

I don't have much application library knowledge, so I don't know which six types there are.

See here:
http://wiki.amigaos.net/wiki/PrefsObjects#Object_Types
Smoke me a kipper, I'll be back for breakfast!

AmigaOne X5000 @ 2GHz / 4GB RAM / Radeon R5 230 / ESI Juli@ / AmigaOS 4.1 Final Edition
SAM440ep-flex @ 667MHz / 1GB RAM / Radeon 9250 / AmigaOS 4.1 Final Edition
User avatar
trixie
 
Posts: 373
Joined: Thu Jun 30, 2011 3:54 pm
Location: Czech Republic

Re: PrefsObject

Postby mritter0 » Mon Oct 05, 2015 6:46 pm

I haven't heard back from my PM to Trixie on getting some example code. Does anyone have an example to get me started?
Workbench Explorer - A better way to browse drawers
User avatar
mritter0
 
Posts: 212
Joined: Mon Aug 25, 2014 10:41 pm
Location: Bettendorf, IA, USA

Re: PrefsObject

Postby javierdlr » Mon Oct 05, 2015 8:58 pm

Not sure if its what you want, but I use an XML file to store Mixer.docky prefs (SoundVolume and Mute), here it's a snnipet:

XML looks like this:
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pobjects PUBLIC "-//Amiga Inc.//DTD POBJECTS 1.0//EN" "http://www.amiga.com/DTDs/PrefsObjects-1.0.dtd">
<pobjects version="1.0">
<dict>
   <key>Volume-Mute</key>
   <array>
      <integer>100</integer>
      <bool>FALSE</bool>
      <integer>100</integer>
      <bool>FALSE</bool>
      <integer>100</integer>
      <bool>FALSE</bool>
      <integer>100</integer>
      <bool>FALSE</bool>
   </array>
</dict>
</pobjects>


And source for reading such xml:
Code: Select all
extern uint32 sliderVal[SC_MAX];
extern BOOL buttonMute[SC_MAX];
...
void ReadXMLcfg(char *filename, struct DockyData *dd)
{
 PrefsObject *dict;
 uint32 err = 0;

 dict = IPrefsObjects->PrefsDictionary(NULL, NULL, ALPO_Alloc,0, TAG_DONE);

 err = IPrefsObjects->ReadPrefs(dict, READPREFS_FileName,(ULONG)filename, TAG_DONE);
 if(err!=0 && err!=ALPOEF_FILEERROR)
  DoMessage("Warning: Can't read/load XML settings.", REQIMAGE_WARNING, dd);
 else
 {
  PrefsObject *soundcard = IPrefsObjects->DictGetObjectForKey(dict, "Volume-Mute");
  if(soundcard)
  {
   int32 count;
   struct ALPOObjIndex oi;

   IPrefsObjects->PrefsArray(soundcard, NULL, ALPOARR_GetCount,&count, TAG_DONE);
   for(oi.index = 0; oi.index < count; oi.index++)
   {
    IPrefsObjects->PrefsArray(soundcard, NULL, ALPOARR_GetObjAtIndex,&oi, TAG_DONE);
    if(oi.obj)
    {
     int32 vol;
     BOOL mut;
//IDOS->Printf("[XML]object %2ld: ",oi.index);
     IPrefsObjects->PrefsNumber(oi.obj, &err, ALPONUM_GetLong,&vol, TAG_DONE);
     if(!err)
      sliderVal[oi.index>>1] = vol;

     oi.index++;
     IPrefsObjects->PrefsArray(soundcard, NULL, ALPOARR_GetObjAtIndex,&oi, TAG_DONE);
     IPrefsObjects->PrefsNumber(oi.obj, &err, ALPONUM_GetBool,&mut, TAG_DONE);
     if(!err)
      buttonMute[oi.index>>1] = mut;
//IDOS->Printf("[R:%ld]sliderVal=%ld buttonMute=%ld\n",oi.index>>1,sliderVal[oi.index>>1],buttonMute[oi.index>>1]);
    }
   }
  } // END soundcard
 }
 IPrefsObjects->PrefsDictionary(dict, NULL, ALPO_Release,0, TAG_DONE);
}


(full sources are Mixer archive(openamiga, os4depot)
User avatar
javierdlr
Beta Tester
Beta Tester
 
Posts: 371
Joined: Sun Jun 19, 2011 11:13 pm
Location: Donostia (GUIPUZCOA) - Spain

Re: PrefsObject

Postby trixie » Tue Oct 06, 2015 2:49 pm

@mritter0

mritter0 wrote:I haven't heard back from my PM to Trixie on getting some example code. Does anyone have an example to get me started?

Sorry I forgot to check my PM. Was the current example in the wiki not enough? The easiest way is really to register your app with REGAPP_LoadPrefs, TRUE, get the prefs dictionary object via GetApplicationAttrs(), and then manipulate the settings via the respective getter functions - DictGetBoolForKey(), DictGetIntegerForKey() etc. Values are set using DictSetObjectForKey(). Saving to the XML file is done through WritePrefs().

What Javier is suggesting is an alternative: you allocate your own prefs dictionary through PrefsDictionary() and then ReadPrefs() into it. The rest is pretty much the same.

I'm still working on improving the wiki page but it takes time, unfortunately :(

EDIT: This is what I use in WordNet to load/save settings:

Code: Select all
int load_settings(uint32 appID)
{
 PrefsObject *prefsObj = NULL;

 // Obtain the prefs dictionary.
 IApplication->GetApplicationAttrs(appID, APPATTR_MainPrefsDict, &prefsObj, TAG_DONE);

 if ( prefsObj )
  {
   // Load prefs (or use defaults).
   settings.width      = IPrefsObjects->DictGetIntegerForKey(prefsObj, PREFSKEY_WINWIDTH, WINWIDTH_DEFAULT);
   settings.height     = IPrefsObjects->DictGetIntegerForKey(prefsObj, PREFSKEY_WINHEIGHT, WINHEIGHT_DEFAULT);
   settings.histlen    = IPrefsObjects->DictGetIntegerForKey(prefsObj, PREFSKEY_HISTLEN, HISTLEN_DEFAULT);
   settings.lingmode   = IPrefsObjects->DictGetBoolForKey(prefsObj, PREFSKEY_LINGMODE, LINGMODE_DEFAULT);
   settings.fulldesc   = IPrefsObjects->DictGetBoolForKey(prefsObj, PREFSKEY_FULLDESC, FULLDESC_DEFAULT);
   settings.unfold     = IPrefsObjects->DictGetBoolForKey(prefsObj, PREFSKEY_UNFOLD, UNFOLD_DEFAULT);
   settings.dclick     = IPrefsObjects->DictGetBoolForKey(prefsObj, PREFSKEY_DCLICK, DCLICK_DEFAULT);
   settings.showfreq   = IPrefsObjects->DictGetBoolForKey(prefsObj, PREFSKEY_SHOWFREQ, SHOWFREQ_DEFAULT);
   settings.escquit    = IPrefsObjects->DictGetBoolForKey(prefsObj, PREFSKEY_ESCQUIT, ESCQUIT_DEFAULT);
   settings.helptips   = IPrefsObjects->DictGetBoolForKey(prefsObj, PREFSKEY_HELPTIPS, HELPTIPS_DEFAULT);

   return RETURN_OK;
  }

 else return RETURN_FAIL;
}



int save_settings(uint32 appID)
{
 PrefsObject *prefsObj    = NULL;
 int          retValue    = RETURN_FAIL;

 // Obtain the prefs dictionary.
 IApplication->GetApplicationAttrs(appID, APPATTR_MainPrefsDict, &prefsObj, TAG_DONE);

 if ( prefsObj )
  {
   IPrefsObjects->DictSetObjectForKey(prefsObj, IPrefsObjects->PrefsNumber(NULL, NULL,
         ALPONUM_AllocSetLong, settings.width,
         TAG_DONE), PREFSKEY_WINWIDTH);
   IPrefsObjects->DictSetObjectForKey(prefsObj, IPrefsObjects->PrefsNumber(NULL, NULL,
         ALPONUM_AllocSetLong, settings.height,
         TAG_DONE), PREFSKEY_WINHEIGHT);
   IPrefsObjects->DictSetObjectForKey(prefsObj, IPrefsObjects->PrefsNumber(NULL, NULL,
         ALPONUM_AllocSetLong, settings.histlen,
         TAG_DONE), PREFSKEY_HISTLEN);
   IPrefsObjects->DictSetObjectForKey(prefsObj, IPrefsObjects->PrefsNumber(NULL, NULL,
         ALPONUM_AllocSetBool, settings.lingmode,
         TAG_DONE), PREFSKEY_LINGMODE);
   IPrefsObjects->DictSetObjectForKey(prefsObj, IPrefsObjects->PrefsNumber(NULL, NULL,
         ALPONUM_AllocSetBool, settings.fulldesc,
         TAG_DONE), PREFSKEY_FULLDESC);
   IPrefsObjects->DictSetObjectForKey(prefsObj, IPrefsObjects->PrefsNumber(NULL, NULL,
         ALPONUM_AllocSetBool, settings.unfold,
         TAG_DONE), PREFSKEY_UNFOLD);
   IPrefsObjects->DictSetObjectForKey(prefsObj, IPrefsObjects->PrefsNumber(NULL, NULL,
         ALPONUM_AllocSetBool, settings.dclick,
         TAG_DONE), PREFSKEY_DCLICK);
   IPrefsObjects->DictSetObjectForKey(prefsObj, IPrefsObjects->PrefsNumber(NULL, NULL,
         ALPONUM_AllocSetBool, settings.showfreq,
         TAG_DONE), PREFSKEY_SHOWFREQ);
   IPrefsObjects->DictSetObjectForKey(prefsObj, IPrefsObjects->PrefsNumber(NULL, NULL,
         ALPONUM_AllocSetBool, settings.escquit,
         TAG_DONE), PREFSKEY_ESCQUIT);
   IPrefsObjects->DictSetObjectForKey(prefsObj, IPrefsObjects->PrefsNumber(NULL, NULL,
         ALPONUM_AllocSetBool, settings.helptips,
         TAG_DONE), PREFSKEY_HELPTIPS);
   IPrefsObjects->DictSetObjectForKey(prefsObj, IPrefsObjects->PrefsString(NULL, NULL,
         ALPOSTR_AllocSetString, settings.homepage,
         TAG_DONE), PREFSKEY_HOMEPAGE);
   IPrefsObjects->DictSetObjectForKey(prefsObj, IPrefsObjects->PrefsString(NULL, NULL,
         ALPOSTR_AllocSetString, settings.docfile,
         TAG_DONE), PREFSKEY_DOCFILE);

      // Write preferences.
   if ( IPrefsObjects->WritePrefs(prefsObj,
         WRITEPREFS_AppID, appID,
         WRITEPREFS_WriteENVARC, TRUE,
         TAG_DONE) == 0 ) retValue = RETURN_OK;
  }

 return retValue;
}
Smoke me a kipper, I'll be back for breakfast!

AmigaOne X5000 @ 2GHz / 4GB RAM / Radeon R5 230 / ESI Juli@ / AmigaOS 4.1 Final Edition
SAM440ep-flex @ 667MHz / 1GB RAM / Radeon 9250 / AmigaOS 4.1 Final Edition
User avatar
trixie
 
Posts: 373
Joined: Thu Jun 30, 2011 3:54 pm
Location: Czech Republic

Re: PrefsObject

Postby mritter0 » Wed Oct 07, 2015 2:03 am

Thanks guys. The loading code on the wiki doesn't do me any good if I can't save my prefs first. ;)

I would still like to see a fully loaded example that saves/loads a complicated prefs file. As in, Screen settings grouped, Window settings grouped, etc. Not just a straight list of items.

This will get me started.
Workbench Explorer - A better way to browse drawers
User avatar
mritter0
 
Posts: 212
Joined: Mon Aug 25, 2014 10:41 pm
Location: Bettendorf, IA, USA

Re: PrefsObject

Postby mritter0 » Wed Oct 07, 2015 2:16 am

Now I am going to get nit-picky:

To be consistent across applications, what is the prefs filename extension? Xxxx.prefs or Xxxxx.xml

I already see a mix of the two. I like .xml. Pick one, Style Guide maintainer. :P
Workbench Explorer - A better way to browse drawers
User avatar
mritter0
 
Posts: 212
Joined: Mon Aug 25, 2014 10:41 pm
Location: Bettendorf, IA, USA

Re: PrefsObject

Postby broadblues » Wed Oct 07, 2015 12:41 pm

#?.prefs ofcourse you don't call older prefs formats in IFF #?.iff

But it doesn't matter really.
User avatar
broadblues
AmigaOS Core Developer
AmigaOS Core Developer
 
Posts: 538
Joined: Sat Jun 18, 2011 3:40 am
Location: Portsmouth, UK

Re: PrefsObject

Postby trixie » Wed Oct 07, 2015 3:10 pm

@mritter0
mritter0 wrote:To be consistent across applications, what is the prefs filename extension? Xxxx.prefs or Xxxxx.xml


The Application Library uses .xml by default.

I would still like to see a fully loaded example that saves/loads a complicated prefs file. As in, Screen settings grouped, Window settings grouped, etc. Not just a straight list of items. This will get me started.

This is why it's important to specify what exactly you are after. If you say things like "to get me started", it appears that you need to learn the basics. So you've got what you've got: examples describing the basics :-) Anyway, I'll try to dig out something more complex for you.
Smoke me a kipper, I'll be back for breakfast!

AmigaOne X5000 @ 2GHz / 4GB RAM / Radeon R5 230 / ESI Juli@ / AmigaOS 4.1 Final Edition
SAM440ep-flex @ 667MHz / 1GB RAM / Radeon 9250 / AmigaOS 4.1 Final Edition
User avatar
trixie
 
Posts: 373
Joined: Thu Jun 30, 2011 3:54 pm
Location: Czech Republic

Re: PrefsObject

Postby mritter0 » Sun Oct 11, 2015 11:46 pm

I am leaning more towards what BroadBlues suggested. But what salass00 suggested is just as good. But I would like to see some other tags added:

Code: Select all
<pobjects version="2.0">
<dict>
   <Application>MyProgram</Application>
   <Version>1.0</Version>
   <!-- some other tags -->

   <!-- this is more compact -->   
   <integer key="WindowX">79</integer>
   <integer key="WindowY">33</integer>
   <integer key="WindowWidth">1066</integer>
   <integer key="WindowHeight">631</integer>
   <string key="SomeText">Text message</string>
   <bool key="Verify">TRUE</bool>
   
   
   <!-- Be able to add comment lines and blank lines -->   
   <item key="Window">
      <array>
         <item key="WindowX">
            <integer>79</integer>
         </item>
         <item key="WindowY">
            <integer>33</integer>
         </item>
         <item key="WindowWidth">
            <integer>1066</integer>
         </item>
         <item key="WindowHeight">
            <integer>631</integer>
         </item>
      </array>
   </item>
</dict>
</pobjects>


Name and version, comment lines, and blank lines to group better and for easier reading.

For an array, you loop through the count of items. Not good. Should "search" by name like do for individual items. That way if items are added/removed with new version of program it won't affect anything. Then can also be added/removed in any order/place. At least that is what the Mixer code shows.

Then can do this:

Code: Select all
PrefsObject *MainDict, *WindowArray;

Name=IPrefsObjects->DictGetIntegerForKey(MainDict,"Application","");
Version=IPrefsObjects->DictGetIntegerForKey(MainDict,"Version","");

WindowArray=IPrefsObjects->DictGetIntegerForKey(MainDict,"Window",NULL);  // find the Window array
if (WindowArray)
{
    Prefs->WindowX=IPrefsObjects->DictGetIntegerForKey(WindowArray,"WindowX",10);
}
else
{
    // fill in default values
}
.....
Prefs->Verify=IPrefsObjects->DictGetIntegerForKey(MainDict,"Verify",TRUE);
.....
Workbench Explorer - A better way to browse drawers
User avatar
mritter0
 
Posts: 212
Joined: Mon Aug 25, 2014 10:41 pm
Location: Bettendorf, IA, USA

PreviousNext

Return to General Developer Support

Who is online

Users browsing this forum: No registered users and 6 guests