Jump to content

Standalone file date changer with GUI, multilanguage interface and list management (Version 4h)


obiwanceleri
 Share

Recommended Posts

Because I like my collections to be clean and shiny I often alter the "Created", "Modified" and "Accessed" properties of my files. 

The freeware I found to do this are, at best cumbersome. So I decided to roll my own.

Here's what you're getting

- A fully multilingual interface that adapts to your OS's language  (IMPORTANT: since I only speak French and English, any help to correct / add translations is welcome!)
- Translations done via any spreadsheet program that can export to .CSV. Libre Office example included. You rename the CSV to "DacoDate.res" and you're off to the races
- At compile time you can have the required DacoDate.res file extracted automagically
- Two save slots to save dates for a future use
- A "one liner" mode so any change to to the "Created" section will automatically copy to the "Modified" and "Accessed" fields
- Many possible permutations (copying one line to another, etc.)
- The capacity to export and import lists
- A progress bar to show you which file was "touched"
- A really small UI (I don't like big, clunky stuff)
- Pretty nice speed considering it's AutoIT we're talking about!
- Command line support (pretty basic: you can only pass filenames for the moment)
- A log file so you can retrace which file has had it's date and time modified and a status if there was an error
- A secret keyboard shortcut (Ctrl+Shift+Alt+R) to revert the program back to it's initial language / settings

Some of the code in this program comes from @Guiness : _GUIDisable() THANK YOU!
It's packaged as an include file. Put it in the folder at run / compile time.

Still some more code comes from @KaFu; the smallest hyperlink code ever! THANK YOU!

Links to the corresponding webpages can be reached in the program's about section. 

The comments in the .au3 file are in French ... but you'll see I named the procedures in an intuitive way: _(what this is working on)_(what GUI it's about)_(what it's doing)

Particularities

If you check the translation table, you'll notice the last column has a "!" in it. It was required so Libre Office properly exports the empty fields. Those fields are truncated after they're imported into AutoIt anyways. 

The translation table contains double the items in the GUI; per example, a given line gives a button it's name, the next is the tooltip.

If there's no tooltip, you can use that space to translate something else. I've done that too (line 2 is only there to tell the user what language each column represents).

For your convenience (and mental health) I've also coloured the spreadsheet so that each corresponding GUI has it's background color.

Still in the translation table, the left & right accolades and the tilde are reserved; they are converted to @CRLF, memory button content and program version number

I've also removed all comas from the translations (since it is a coma-separated file). 

While I did as much sanity checks as possible, some bugs can surely crop out. Not for mission critical stuff :)

You could also get some funky results if you give the program invalid values on purpose LOL

IMPORTANT: The translations are done with Google Translate so therefore they are hit-and-miss. If you can help I'd be grateful :) Note: My girlfriend says she'll do the German one (unless someone's faster than her LOL).

I've tried to keep the code clean and logical. If anyone has suggestions to make it better, I'm a taker :)

If you like some of my code and want to use it, it's free but giving me some credit / thanks would be awesome :)

Louis

 

UPDATED, Version 4h, 28th February 2022:

- More references to the code I'm using in program and About screen
- Work on accepting lists through drag and drop (but still isn't integrated).
- File list counter now displays properly in the button at the bottom of the GUI
- Issues with $aFICHIER_Liste[] not being properly initialized and crashing the program in certain circumstances
- Give a name to the sub-menu windows
- Integrate a list of all the functions so it's easy to jump with Control-J in Scite
- Documented each line of code AND described each LOCAL variable on it's own line
- Asks user if he wants to quit after exiting the main interface
- Much code cleanup and removing of commands that didn't do anything / were not being run / needed (i.e.: closing a control group???)
- Don't show progress bar BEFORE asking you to select files
- Convert some registry entries from REG_SZ to REG_DWORD
- During reading of the command line, get rid of entries that point to a folder instead of a file
- Exiting the import / export process should not have you quit the program anymore
- You can now import a list from a .LOG file created by DacoDate previously.
- Much tinkering to get the GUI to refresh faster. Deleting unused code and streamlining the copying of data to the GUI. 
- A zillion bugs squashed
IMPORTANT: You also need to download the DacoDate.res ressource file if you're upgrading. If you don't you might not see the proper text on screen.

UPDATED, version 4g, 24th February: 

- Text in English if missing ressource file
- "About" window has actual hyperlinks
- Better screen management for other languages (still working on it. 
- Colors as variables (instead of "magic numbers")
- Reset values will now reset language to system language instead of French LOL

 

 

DacoDate.res DacoDate04h Translation.csv DacoDate04h Translation.ods DacoDate04h.au3 GUIDisable.au3

Edited by obiwanceleri
Bump up version from 4g to 4h

Help a newbie, comment your code!

Link to comment
Share on other sites

  • obiwanceleri changed the title to Standalone file date changer with GUI, multilanguage interface and list management (Version 4h)

A little primer on how I created a multilingual interface, for those who are interested.

For starters, I prefer using arrays in order to manage my GUIs. It's so much easier to debug with _ArrayDisplay().

DacoDate mainly sets up six arrays:
1. One that contains all the translations ($aGUI_LANG), 
2. The main program GUI ($aGUI_Main)
3. The "Memory" sub-menu ($aGUI_Memoire)
4. The "Option" sub-menu ($aGUI_Option)
5. The "A Propos" ($aGUI_APropos)
6. The "Progress" sub-menu ($aGUI_Progress)

Array #1 ($aGUI_LANG) has two dimensions. The first is the line number to be translated, the second is the language in which this line is translated to.

Essentially this is what it looks like:

English  French       Italian            ...
[Hello]    [Bonjour]   [Buongiorno]  ...
[Bye]       [Au revoir] [Arrivederci]   ...
...             ...                 ...

The order of the languages is inspired by the excellent example from the AutoIt helpfile. Check out the appendix --> @OSLang Values

Arrays #2-6 are simple arrays (from 0 to whatever) and host the return values for the creation of each GUI element

I quickly ran into a feature I wanted to add: not only translate each line of text but ALSO translate each tooltip.
There was two ways of going about this and I'll explain my choice

Method 1 : add an extra dimension to the array --> $aGUI_Lang[Line][Language][Item]
Method 2 : double the lines in the array: odd number = actual text, even number = tooltip

I chose method 2 simply for the fact that displaying the content of a 3-dimension array isn't very convenient.

So that basically means there's two lines per item, giving you the following result 

English                 French                     Italian                   ...
[Hello]                   [Bonjour]                 [Buongiorno]        ...
[Click here]           [Cliquez ici]              [Clicca qui]            ...
[Bye]                      [Au revoir]               [Arrivederci]          ...
[Don't click here] [Ne cliquez pas ici] [Non fare clic qui] ...
...                  ...                               ...

In order to restore the values back to the GUI you'd do commands like these:

$aGUIMain[0] = GUICreate($aGUI_Lang[0][n]) ; Create the main GUI, 'n' is replaced by the language / variable you want
$aGUIMain[1] = GUICtrlCreateButton($aGUI_Lang[2][n],Top,Left) ; Next is a button. Notice how we skipped from [0] to [2] because the main GUI has no tooltip
GUICtrlSetTip($aGUIMain[1], $aGUI_Lang[3][n]) ; Now we set the tip. Notice how [3] is an odd number.

In my program I go about it programmatically by using for / next loops:

For $i = 0 To UBound($aGUI_Main) - 1 ; Go through all values in the main GUI array
        If $aGUI_Lang[$i * 2][$iLang] <> "" Then GUICtrlSetData($aGUI_Main[$i], $aGUI_Lang[$i * 2][$iLang]) ; If it isnt empty, set the value. $iLang is the language selected the user. Notice how $i is multiplied by two to factor in the text / tooltip design
        If $aGUI_Lang[($i * 2) + 1][$iLang] <> "" Then GUICtrlSetTip($aGUI_Main[$i], $aGUI_Lang[($i * 2) + 1][$iLang]) ; Do the same with the tooltip. Notice how its all + 1
    Next 

This also applies to message boxes and different tools but the odd fields aren't used for tooltips:

$sSelection = FileOpenDialog($aGUI_Lang[258][$iLang], $sDefaultFolder, $aGUI_Lang[259][$iLang], BitOR($FD_FILEMUSTEXIST, $FD_PATHMUSTEXIST))
; First $aGUI_Lang[][] value is title of the window, then the folder where the file selector will start, then the second $aGUI_Lang[][] value represents the filter : "Log (*.log)" and finally the options (file and path must exist).

Same with any MsgBox command where the odd field is the actual question while the even field is the window title. 

$iMsgBoxAnswer = MsgBox(292, $aGUI_Lang[242][$iLang], $aGUI_Lang[243][$iLang]) ; "Voulez vous exporter la liste?", "Voulez-vous exporter la liste de fichiers?"

Notice how I commented the original text value. It can get complicated real quick so commenting your code is essential

 

Some more program mechanics:

Now the whole idea is a user can change the GUI language on-the-fly. There's two ways (I can see) of going about it:
- Delete and re-creating the GUI each time
- Refresh the parts of the GUI that can change

In terms of refreshing speed the latter is obviously the best choice. So I've split the GUI creation into two parts:
- _GUI_Main ; This part contains all the "Create" functions for ALL the GUIs, including sub-menus. We'll only run this ONCE.
- _GUI_Peupler : This part "populates" all the GUIs, including GUICtrlSetData, GUICtrlSetTooltip, GUICtrlSetState and GUISetState 

So the logic behind this is if a user selects another language, we immediately call _GUI_Peupler() and Bob's your uncle

I've also streamlined the refresh as much as I could so that there is as little wait time as possible to get the GUI in the desired language.

As an added bonus I also created an "emergency" button so that all values (including the language) are reset to their default values and the language is set once again to the OS's current language. Try Ctrl+Shift+Alt+'r'.

 

Creating the translation file:

Last part: how do you create a translation file and where do you put it? There's at least two ways to proceed here.

The first one is quite cumbersome and implies creating the array inline. Setting the cells is a bit like this. It's a major chore:

Global Const $aGUI_Lang[50][3] ; 50 lines, 3 languages
$aGUI_Lang[0][0] = "Hello"
$aGUI_Lang[0][1] = "Bonjour"
$aGUI_Lang[0][2] = "Buongiorno"
$aGUI_Lang[1][0] = "Click here"
$aGUI_Lang[1][1] = "Cliquez ici"
$aGUI_Lang[1][2] = "Clicca qui"
...

The second way is much better (specially if you've got a ton of messages / languages to translate) but as a downside requires an external file. 

I've used LibreOffice's Calc since it's free. I guess you could also use Excel or Google Sheets. Whatever floats your boat. 

Calc is ideal to make a two-dimentionnal array. As per the included example, each row (two by two) is a GUI pair (text and tooltip) and each column is a different language.

IMPORTANT: In order to export to a compatible file for this program you must do the following steps in Calc : File --> Create a copy --> Type, choose CSV --> type in "DacoDate.res" as filename  --> when prompted for options, don't touch anything except making sure "Put values between quotes" is NOT checked. 

IMPORTANT: As a limitation, you must not use commas in any of your entries, since it will obviously bork the program. You could replace the commas by semicolons. Just make sure you tell _FileReadToArray() about it (see below). 

You'll notice in the joined .ODS file the last column has a "!" included in it. I found that if I didn't put something in the last field, Calc would simply export the first empty field and then go to the next line. That's why as soon as the ressource file is imported in AutoIt, I redim the last column out:

$ierr = _FileReadToArray(@ScriptDir & "\" & "DacoDate.res", $aTempo, $FRTA_NOCOUNT, ",") ; Import resource file, put it in "$aTempo, don't use cell 0 to indicate count and automagically seperate fields using a comma
ReDim $aTempo[UBound($aTempo)][UBound($aTempo, 2) - 1] ; Leave rows as they are. Remove last column

 

A few downsides:

In conclusion, there are a few downsides to using this approach to translate your program. Although for me the advantages far outweigh the drawbacks. 

1. The code can get quite cryptic at times so you need to put whatever text value you expect in the comments. COMMENT, COMMENT, COMMENT!
2. You need to plan ahead. If you insert rows and columns too often you are just asking for trouble. If need be put empty rows / columns so you can add extra values later
3. Keep a list handy of what row says what. My file has grown from 20 to 260 ish lines and will probably grow by the time I'm finished. 

So that's it. Hopefully this will come in handy. 
And if someone knows a few languages in the list I'd appreciate a *proper* translation ;)

Edited by obiwanceleri
So much typos!

Help a newbie, comment your code!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...