News:

Simutrans Tools
Know our tools that can help you to create add-ons, install and customize Simutrans.

Question about GUI and directory access.

Started by Markohs, April 30, 2012, 10:03:24 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Markohs

Quote from: prissi on November 06, 2012, 09:50:30 PM
Looking close at your code I have some questions about coding style. What kind of comment is "/*!" which is new to me. Since those functions are anyway no completely documented (@param etc) would be a normal comment "//" not better for a single liner? Same for \author, should it be not rather @author?

Oh, I forgot this. Well, I tried to follow more or less what we talked about but never ended fixing in http://forum.simutrans.com/index.php?topic=4672.125 , /** it's exactly the same than /*! , and yes, I should have sticked to /** and @param and not \param, since it's way more common in the rest of the code. Changing this too. Even I did not comment 100% of the functions, I did comment many, and I'd let /** stay and not //, since doxygen won't pick //

You can see what does it generate in:

https://dl.dropbox.com/u/30024783/doxgui/html/classsavegame__frame__t.html

EDIT: I see you already changed some of the things you commented me here, I'll fix the rest soon. :)

prissi

I though doxygen would pick up /// for one liner. Well, I hacked a removal of the sole entry into the code. Not sure, if this was the right place, though.

About the idea with "PROGRAM_DIR"+"\save" etc. with different colors: That seem are very good idea.

Before doing stuff, just use the latest revision!

Ters

USERDIR and PROGRAM_DIR aren't pretty on the eyes, and I suspect that is especially not so for those that are not computer experts. It should follow the nomenclature for the platform, such as "My documents" or "Documents" for the former on Windows. (I wonder if most non-hardcore Windows users know what c:\ is nowadays.)

Fabio

Quote from: Ters on November 07, 2012, 05:46:18 AM
It should follow the nomenclature for the platform, such as "My documents" or "Documents" for the former on Windows.

I agree. I wonder if there's a way to retrieve the localized denomination for those from some API.

Markohs

Yes, Fabio, it's possible and I'll do it that way. Problem will be wide char languages I think, dunno how will it work in japanese. Making some tests.

On unix-like platforms "~user/" will be clear enough I guess

Fabio

Quote from: Markohs on November 07, 2012, 12:59:54 PM
On unix-like platforms "~user/" will be clear enough I guess

You could also use ~markohs/ grabbing the active user (but I don't usually use *nix systems, so I might be wrong).

prissi

well but then for the program dir?

MAybe rather have two text for translator "PROGRAM_DIR" "USER_DIR" or maybe "HOME_DIR" "MY_DOCUMENT_DIR" for Unix/mac. Also "Programme" or "Program files (x86)" is not neccessarily the location of the program folder

Markohs

To finish this I'd like to add some code that might not work in old Windows 98/95 machines, are we still giving support to those platforms? The are more than 14 years old...

The code in question is:


   CHAR szPath[MAX_PATH];

   SHGetFolderPathA(NULL, CSIDL_MYDOCUMENTS, NULL, 0, szPath);

   SHFILEINFOA sfi = {0};

   SHGetFileInfoA(szPath,-1,&sfi,sizeof(sfi), SHGFI_DISPLAYNAME);

   printf("%s %s", szPath, sfi.szDisplayName);


That results in "C:\Users\Markohs\Documents" and "My Documents" in my w7 system (I have it in english).

For program dir I'd just print "Simutrans Installation" or some fixed string that whould be translated in each language. For user_dir I'd use the code above in windows, and ~/simutrans/save in linux.

Ters

Looks like MSDN labels everything as from 2000 Pro/Server or later, even functions I know have been around "forever". But if it compiles with #define WINVER 0x400 (which seems to be the default in the headers for mingw32), it should work on Win95.

Markohs

oh, great! I guess they did that in msdn because those platform are outside of the supported platforms. thank you ters.

I'll change it then, using regedit in the entry refered in dr_queryhomedir (or similar) warns that those entries are deprecated.

prissi

The results in "C:\Documents and Settings\prissi\My Documents\simutrans" in windows XP. Not sure if this can be fit into the dialoge. Maybe some shorten of paths "C:\Docu...si\My Documents\simutrans" (i.e. take out x characters from the 8th onwards in steps of five until width fits dialog width.)

ShellGetFolderA will not return the user path you want. In this form it will only work in Win2000, in Xp and higher it will return the user path of the default users. It must be -1 for XP and up for the current user. See http://msdn.microsoft.com/en-us/library/windows/desktop/bb762181%28v=vs.85%29.aspx

Zeno

Even ignoring everything before "My Documents" would do the job, as the full path doesn't matter much in Windows systems. Thus "My documents\simutrans" should be enough.

Markohs

SHGetFileInfoA doesn't translate C:\Documents and Settings\prissi\My Documents to "My Documents"?

Markohs

The idea is that  SHGetFileInfoA turns "C:\Documents and Settings\prissi\My Documents" or "C:\Users\prissi\Documents" to "My documents", at least in Windows 7.

Markohs

I've tested that code in XP too and works, can anybody test it too plz?

Download, might need install of http://www.microsoft.com/en-us/download/details.aspx?id=30679

On XP in spanish I get:
Quote
SHGetFolderPathA: C:\Documents and Settings\Administrador\Mis documentos SHGetFileInfoA: Mis documentos

On windows 7 english:

Quote
SHGetFolderPathA: C:\Users\marcos\Documents SHGetFileInfoA: My Documents

I just made a console Win32 applicattion in VS2010 and the code is:

Quote
// testpath.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
CHAR szPath[MAX_PATH];

   SHGetFolderPathA(NULL, CSIDL_MYDOCUMENTS, NULL, 0, szPath);

   SHFILEINFOA sfi = {0};

   SHGetFileInfoA(szPath,-1,&sfi,sizeof(sfi), SHGFI_DISPLAYNAME);

   printf("SHGetFolderPathA: %s SHGetFileInfoA: %s", szPath, sfi.szDisplayName);
}

prissi

It does not return the path to my files on the first hand, since in XP and later you have to pass -1 as third parameter to SHGetFolderPathA.

Also maybe the reduction does not work because my "Dokumente" folder is on another disk. That is not true for default user though. Even more, if installed protable, the file will not be in my document anyway but in the simutrans folder. (Of course you know this.) Even "user_dir" could point quite well to other locations than my document.

Markohs

Strange, works here in my computer, and passing -1 as third parameter will return the documents folder of the default user, that's not what we want... I'll test passing it the user as the third parameter. I'll move my documents folder too to test.

When you refer to the portable installation do you refer to "-singleuser" param and 'multiuser = !(contents.get_int("singleuser_install", !multiuser)==1  ||  !multiuser); ' in simmain.cc?

Markohs

How did you changed the my documents folder prissi? I did change on explorer->right-click->properties->change destination and accept. And SHGetFolderPathA returned the correct path (with third parameter NULL), and FileInfoA showed the name of the directory:


Markohs

#123
Using PIDL looks like it's working better. Even it works quite different across windows versions.

Prissi, using -1 as third parameter won't work, that will return the default user document path, and that's not what we want. NULL is working good here.

Quote
   CHAR szPath[MAX_PATH];
   SHGetFolderPathA(NULL, CSIDL_MYDOCUMENTS, NULL, 0, szPath);
   

   LPITEMIDLIST pidl=NULL;
   if (!SUCCEEDED(SHGetFolderLocation(NULL, CSIDL_MYDOCUMENTS, (HANDLE) -1, 0, &pidl)) ){
      printf("errr");
   }

   SHFILEINFOA sfi = {0};

   if (!SUCCEEDED(SHGetFileInfoA((LPCSTR)pidl,-1,&sfi,sizeof(sfi),  SHGFI_PIDL| SHGFI_DISPLAYNAME) )) {
      printf("errr");
   }

   printf("SHGetFolderPathA: %s SHGetFileInfoA: %s", szPath, sfi.szDisplayName);

Windows 8 SPANISH (strange, FileInfoA doesn't translate)

SHGetFolderPathA: C:\Users\marcos\Documents SHGetFileInfoA: Documents

Windows 7 english:

SHGetFolderPathA: C:\Users\marcos\Documents SHGetFileInfoA: Documents

Windows XP Spanish:

SHGetFolderPathA: C:\Documents and Settings\Administrador\Mis documentos SHGetFileInfoA: Mis documentos

Windows XP Spanish moving My documents folder:

SHGetFolderPathA: E:\SIMUTEST SHGetFileInfoA: Mis documentos

Updated the binary if you want to test. https://dl.dropbox.com/u/30024783/testpath.exe

EDIT: NOTE: Windows 7 and 8 in the registry key Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders (the one we use now) has an entry saying:

!Do not use this registry key
Use the SHGetFolderPath or SHGetKnownFolderPath function instead

So might be time to change this anyhow.

VS

Windows 7 Czech: Documents
(might be Dokumenty...)

My projects... Tools for messing with Simutrans graphics. Graphic archive - templates and some other stuff for painters. Development logs for most recent information on what is going on. And of course pak128!

prissi

Anyway, where are you planning to put this code? And what about the case when userdir != My documents? (Like for portable installations?)

All those OS specific stuff should go into simsys.cc. (Same is true for the for the deletion too).

The PC here at work is english, so for now I cannot comment.

Markohs

#126
 Right now we have:

umgebung_t::user_dir
umgebung_t::program_dir

I planned to add:

umgebung_t::display_user_dir
umgebung_t::display_program_dir

And use the second ones when printing paths, instead of the first ones. For the file open/save dialogs and anywere it's applicable.

Yes, I planned to implement those in simsys.cc

I also thought it might be a good idea creating utils/fileutils.cc and implement all that OS specific functions there, what do you think?

The portable installation is already coded and don't plan to modify it, the same if can apply. Will just query for display_user_dir if not multiuser.

in simmain.cc


    // init dirs now
    if(multiuser) {
        umgebung_t::user_dir = dr_query_homedir();
    }
    else {
        // save in program directory
        umgebung_t::user_dir = umgebung_t::program_dir;
    }

prissi

I really do not see the purpose of a display name. Sorry this is a stupid concept introduced by Mircrosoft. Those name translation just adds confusion. And it is keeping me stupid, which I detest.

Thus would prefer a generic term like "USER_DIR" or the real full path.

Furthermore on any portable installation and when not installing into program files (anyway recommended), you will see the full dir of simutrans and "My documents". Making stuff just for one platform is no progress and will rather add confusion on multi platform programs. Not to mention systems like Android or Haiku, which effectively are single user OS.

Markohs

#128
M.... okay, will do it that way.

It's the simplest and way of doing it anyway, much less code to write. Using "USER_DIR" and "SIMUTRANS_DIR" then.

Is this ok then?


Ters

Isn't USER_DIR just a display name also? And I doubt less confusing, though perhaps to different groups. Personally, I just need the path relative to the save game directory. No need to prefix it with anything. That just wastes space.

Fabio

It might be a stupid Microsoft invention, but on a Microsoft OS it's the convention AND what the common user expects to find.
E.g. if I want to copy my saves on a pen drive to play them on another pc, I, user, would check where the files are saved and go browsing them.
If I see My documents, I know where they are, if I see c:\... real location, I might be able, too.
But USER_DIR will be unintelligible for most.

prissi

#131
So in the end it is rather "pre-installed" or "user supplied" files. Since one usually will never see those paths except for scenarios (since normally simutrans saves everything else in one path) maybe rather just leave the full path.

I am torn. The program path will be ugly on many systems and especially on portable devices. Also program and user path will most likely end with "simutrans".

If more user prefer "my document" ok let it be it.

EDIT: On windows 7 (german) the name shown by testpath.exe is "Documents" which is neither english nor german. Sounds not helpful to me, as normally this folder is called now "Bibliotheken\Dokumente" by Windows 7. Thus "Documents" will rather add to confusion as it exists nowhere in the system.

Given this, I vote for the full path or "local settings" or similar.

Markohs

Yeah, it's a non trivial decision, what Fabio and Ters say makes sense, but I can understand your reasoning too. I think I'll submit it with SIMUTRANS_DIR and USER_DIR prefixes and you take the final decision, after all you are the boss. ;)

Ters

Quote from: prissi on November 12, 2012, 08:33:16 PM
EDIT: On windows 7 (german) the name shown by testpath.exe is "Documents" which is neither english nor german. Sounds not helpful to me, as normally this folder is called now "Bibliotheken\Dokumente" by Windows 7. Thus "Documents" will rather add to confusion as it exists nowhere in the system.

Documents should be correct name in English on Windows Vista/7 (before that, it would have been My Documents). That it is not translated might have something to do with how, or rather at which level, these things are translated in Vista/7. (More specifically, one might say that Documents is the display name for the directory, but not for the folder. The distinction between directories and folders have become more prominent from Vista onward.)

By the way, SHGetFolderLocation seems to be Windows 2000 and later only. CSIDL_MYDOCUMENTS is for the virtual folder that is a combination of My Documents and Shared Documents, and therefore only available on Windows Vista and later.

A possibility could be to add one separator in the dialog for files form the user directory, and another for files from the simutrans directory, with subseparators under that containing only the relative paths for directories below that, and file buttons below that just like now. Might be too complicated and/or cluttered, though.

prissi

On german XP and window 2000 it returned indeed "Dokumente" which was the expected name. Thank Mircrosoft for adding confusion with every new version. It also does not solve the unix/Mac/haiku problem. Luckily for now it only affects scenarios.

In the end I leave it to makohs, since he spent most of the time on it.

Markohs

CSIDL_PERSONAL might be better than CSIDL_MYDOCUMENTS, will test tomorrow on the computer where I have the virtual machines.

I just commited the patch with prefixes  @6044 , I'll update it if we get a better idea of what we want.


Ters

Did you define WINVER to something for those example snippets you posted on page 5? I had to, or the Win2000+ stuff wouldn't compile.

Markohs

 That code didn't make to repository at the end because of the lack of a reliable way of getting the My documents folder name.

Right now the old method is used:

Quote
   DWORD len = PATH_MAX - 24;
   HKEY hHomeDir;
   if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_READ, &hHomeDir) != ERROR_SUCCESS)
      return 0;
   RegQueryValueExA(hHomeDir, "Personal", 0, 0, (BYTE*)buffer, &len);
   strcat(buffer,"\\Simutrans");

It's implemented in this code at the end:

Quote
   size_t path_len = strlen(umgebung_t::program_dir);

   if (strncmp(name.c_str(),umgebung_t::program_dir,path_len) == 0) {
      sprintf(label_text,"%s %s/%s", translator::translate("Files from: "), translator::translate("SIMUTRANS_DIR"), name.c_str()+path_len);
   }
   else {
      sprintf(label_text,"%s %s/%s", translator::translate("Files from: "), translator::translate("USER_DIR"), name.c_str());
   }


Combuijs

Quote from: Markohs on November 12, 2012, 11:58:23 PM
CSIDL_PERSONAL might be better than CSIDL_MYDOCUMENTS, will test tomorrow on the computer where I have the virtual machines.

I just commited the patch with prefixes  @6044 , I'll update it if we get a better idea of what we want.



Hmm, it is totally unclear what USER_DIR and SIMUTRANS_DIR is. It is actually quite annoying. You would like to see its full directory name, but that might get too long. Is it perhaps an idea to make buttons of USER_DIR and SIMUTRANS_DIR? If you click on it you will see the full name of that directory. Or similar functionality in another way?
Bob Marley: No woman, no cry

Programmer: No user, no bugs



Markohs

A tooltip over it so the full path is shown when you mouseover is enough?

It's hard to reach a point everybody agrees, so maybe just a tooltip will be enough, and let USER_DIR and SIMUTRANS_DIR like it's now.