diff --git a/App/PhotoDemon/Languages/Deutsch_1.xml b/App/PhotoDemon/Languages/Deutsch_1.xml index 418a7d51b1..5701ff685e 100644 --- a/App/PhotoDemon/Languages/Deutsch_1.xml +++ b/App/PhotoDemon/Languages/Deutsch_1.xml @@ -6,7 +6,7 @@ de-DE Deutsch (Helmut Kuerbiss) -6.7.59 +6.7.61 Complete Helmut Kuerbiss (orig. Frank Donckers) @@ -14146,27 +14146,7 @@ Sie können aber auch den Button "Bild öffnen" oben links oder - -forward diagonal - - - - -backward diagonal - - - - -cross - - - - -diagonal cross - - - - + @@ -14280,12 +14260,24 @@ Sie können aber auch den Button "Bild öffnen" oben links oder + + + + + + + + + + + + -2479 +2475 - - - + + + \ No newline at end of file diff --git a/App/PhotoDemon/Languages/Deutsch_2.xml b/App/PhotoDemon/Languages/Deutsch_2.xml index b5055b119e..2748dea7c0 100644 --- a/App/PhotoDemon/Languages/Deutsch_2.xml +++ b/App/PhotoDemon/Languages/Deutsch_2.xml @@ -6,7 +6,7 @@ de-DE Deutsch (rk) -6.7.60 +6.7.62 Nicht abgeschlossen rk (orig. Frank Donckers, Helmut Kuerbiss) @@ -14148,27 +14148,7 @@ oder das Menü "Datei > Öffnen" bzw. "Datei > Importieren". - -forward diagonal - - - - -backward diagonal - - - - -cross - - - - -diagonal cross - - - - + @@ -14282,12 +14262,24 @@ oder das Menü "Datei > Öffnen" bzw. "Datei > Importieren". + + + + + + + + + + + + -2479 +2475 - - - + + + \ No newline at end of file diff --git a/App/PhotoDemon/Languages/Espanol.xml b/App/PhotoDemon/Languages/Espanol.xml index 9ab5cb50f4..0a5e049b2c 100644 --- a/App/PhotoDemon/Languages/Espanol.xml +++ b/App/PhotoDemon/Languages/Espanol.xml @@ -6,7 +6,7 @@ es-MX Español -6.7.62 +6.7.64 completo Plinio C Garcia @@ -14148,27 +14148,7 @@ or los menús Archivo > Importar y Archivo > Abrir. - -forward diagonal - - - - -backward diagonal - - - - -cross - - - - -diagonal cross - - - - + @@ -14282,12 +14262,24 @@ or los menús Archivo > Importar y Archivo > Abrir. + + + + + + + + + + + + -2479 +2475 - - - + + + \ No newline at end of file diff --git a/App/PhotoDemon/Languages/Francais.xml b/App/PhotoDemon/Languages/Francais.xml index 86bc6cbd27..94451ad2a4 100644 --- a/App/PhotoDemon/Languages/Francais.xml +++ b/App/PhotoDemon/Languages/Francais.xml @@ -6,7 +6,7 @@ fr-FR français -6.7.59 +6.7.61 Complete Frank Donckers @@ -14148,27 +14148,7 @@ ou la commande Fichier > Ouvrir et Fichier > Importer menu. - -forward diagonal - - - - -backward diagonal - - - - -cross - - - - -diagonal cross - - - - + @@ -14282,12 +14262,24 @@ ou la commande Fichier > Ouvrir et Fichier > Importer menu. + + + + + + + + + + + + -2479 +2475 - - - + + + \ No newline at end of file diff --git a/App/PhotoDemon/Languages/Indonesian.xml b/App/PhotoDemon/Languages/Indonesian.xml index 38b96c844d..dcab09bac7 100644 --- a/App/PhotoDemon/Languages/Indonesian.xml +++ b/App/PhotoDemon/Languages/Indonesian.xml @@ -6,7 +6,7 @@ id-ID Indonesian -6.6.1 +6.6.3 Complete Ari Sohandri Putra @@ -14153,27 +14153,7 @@ atau menu berkas >buka dan berkas > menu impor. - -forward diagonal - - - - -backward diagonal - - - - -cross - - - - -diagonal cross - - - - + @@ -14287,12 +14267,24 @@ atau menu berkas >buka dan berkas > menu impor. + + + + + + + + + + + + -2479 +2475 - - - + + + \ No newline at end of file diff --git a/App/PhotoDemon/Languages/Italiano.xml b/App/PhotoDemon/Languages/Italiano.xml index dbe3bf4dea..ae07eb706a 100644 --- a/App/PhotoDemon/Languages/Italiano.xml +++ b/App/PhotoDemon/Languages/Italiano.xml @@ -6,7 +6,7 @@ it-IT Italiano -6.7.59 +6.7.61 Completa GioRock @@ -14144,27 +14144,7 @@ o il menù File > Apri e File > Importa. - -forward diagonal - - - - -backward diagonal - - - - -cross - - - - -diagonal cross - - - - + @@ -14278,12 +14258,24 @@ o il menù File > Apri e File > Importa. + + + + + + + + + + + + -2479 +2475 - - - + + + \ No newline at end of file diff --git a/App/PhotoDemon/Languages/Malay.xml b/App/PhotoDemon/Languages/Malay.xml index 1c89dcb46c..3dd916350b 100644 --- a/App/PhotoDemon/Languages/Malay.xml +++ b/App/PhotoDemon/Languages/Malay.xml @@ -6,7 +6,7 @@ ms-MY Malay -6.7.59 +6.7.61 raw machine translation Google Translate @@ -14148,27 +14148,7 @@ or menu Fail > Import dan Fail > Buka. - -forward diagonal - - - - -backward diagonal - - - - -cross - - - - -diagonal cross - - - - + @@ -14282,12 +14262,24 @@ or menu Fail > Import dan Fail > Buka. + + + + + + + + + + + + -2479 +2475 - - - + + + \ No newline at end of file diff --git a/App/PhotoDemon/Languages/Master/MASTER.xml b/App/PhotoDemon/Languages/Master/MASTER.xml index 4e209f04ac..0f4157f1c9 100644 --- a/App/PhotoDemon/Languages/Master/MASTER.xml +++ b/App/PhotoDemon/Languages/Master/MASTER.xml @@ -6,7 +6,7 @@ en-US English (US) - MASTER COPY - 6.7.301 + 6.7.306 Autogenerated - manual inspection still required VBP Text Extraction App (by Tanner Helland) @@ -14042,27 +14042,7 @@ or the File > Open and File > Import menus. - - forward diagonal - - - - - backward diagonal - - - - - cross - - - - - diagonal cross - - - - + @@ -14176,12 +14156,24 @@ or the File > Open and File > Import menus. + + + + + + + + + + + + - 2479 + 2475 - - - + + + \ No newline at end of file diff --git a/App/PhotoDemon/Languages/Portuguese.xml b/App/PhotoDemon/Languages/Portuguese.xml index d3fe9bdd49..fa0ca63643 100644 --- a/App/PhotoDemon/Languages/Portuguese.xml +++ b/App/PhotoDemon/Languages/Portuguese.xml @@ -6,7 +6,7 @@ pt-BR Português -6.7.59 +6.7.61 raw machine translation Google Translate @@ -14148,27 +14148,7 @@ or os menus File> Open e File> Import. - -forward diagonal - - - - -backward diagonal - - - - -cross - - - - -diagonal cross - - - - + @@ -14282,12 +14262,24 @@ or os menus File> Open e File> Import. + + + + + + + + + + + + -2479 +2475 - - - + + + \ No newline at end of file diff --git a/App/PhotoDemon/Languages/Swedish.xml b/App/PhotoDemon/Languages/Swedish.xml index 82e7ffaa52..dfc267e306 100644 --- a/App/PhotoDemon/Languages/Swedish.xml +++ b/App/PhotoDemon/Languages/Swedish.xml @@ -6,7 +6,7 @@ sv-SE Swedish -6.7.59 +6.7.61 raw machine translation Google Translate @@ -14148,27 +14148,7 @@ or Arkiv> Öppna och Arkiv> Importera menyer. - -forward diagonal - - - - -backward diagonal - - - - -cross - - - - -diagonal cross - - - - + @@ -14282,12 +14262,24 @@ or Arkiv> Öppna och Arkiv> Importera menyer. + + + + + + + + + + + + -2479 +2475 - - - + + + \ No newline at end of file diff --git a/App/PhotoDemon/Languages/Vlaams.xml b/App/PhotoDemon/Languages/Vlaams.xml index 0e3d6a3263..6ba68b52ad 100644 --- a/App/PhotoDemon/Languages/Vlaams.xml +++ b/App/PhotoDemon/Languages/Vlaams.xml @@ -6,7 +6,7 @@ nl-BE Vlaams (Nederlands) -6.7.59 +6.7.61 Complete Frank Donckers @@ -14147,27 +14147,7 @@ of de Bestand > Openen en Bestand > Import menu's. - -forward diagonal - - - - -backward diagonal - - - - -cross - - - - -diagonal cross - - - - + @@ -14281,12 +14261,24 @@ of de Bestand > Openen en Bestand > Import menu's. + + + + + + + + + + + + -2479 +2475 - - - + + + \ No newline at end of file diff --git a/Classes/pdParamXML.cls b/Classes/pdParamXML.cls new file mode 100644 index 0000000000..4dc6670a1a --- /dev/null +++ b/Classes/pdParamXML.cls @@ -0,0 +1,395 @@ +VERSION 1.0 CLASS +BEGIN + MultiUse = -1 'True + Persistable = 0 'NotPersistable + DataBindingBehavior = 0 'vbNone + DataSourceBehavior = 0 'vbNone + MTSTransactionMode = 0 'NotAnMTSObject +END +Attribute VB_Name = "pdParamXML" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = True +Attribute VB_PredeclaredId = False +Attribute VB_Exposed = False +'*************************************************************************** +'PhotoDemon Internal Parameter Handler v2 +'Copyright 2014-2015 by Tanner Helland +'Created: 25/March/13 +'Last updated: 03/July/14 +'Last update: start rewriting pdParamString to operate on XML strings instead of pipe-delimited ones +' +'PhotoDemon has unique needs regarding parameter passing. Because it allows the user to record all actions as part of +' macros, the program needs a way to not only trade around parameters, but also store them in a file. +' +'The problem occurs when trying to develop a single system that works with all possible function parameters. Some actions, +' like "Invert Image", require no additional information. Others, like "Curves", require a huge amount of custom data. +' Various functions utilize conceivable every type of value (bool, int, float, custom types, etc), and if a macro is +' recording a function, all those specialized parameters need to be tracked and written to file. +' +'The easiest way to handle that kind of variety from within VB is to use a string. This allows any amount - and type - +' of custom parameter data to be recorded, stored, and easily transferred between functions. +' +'Individual functions therefore rely on this class to create and parse parameter strings for them. +' +'In summer 2015, I moved from a pipe-delimited parameter system (where parameters were listed in order, and retrieved by order) +' to an order-agnostic XML system, where parameters are retrieved by name. This class uses its own XML parsing code, which +' includes a few greatly stripped-down (and speed-optimized) basic XML functions from the main pdXML class. This micro-XML +' parsing code introduces a few restrictions: +' 1) All comparisons are case-sensitive. If you change case in PD's source, you will invalidate old parameters, by design. +' 2) All parameter names must be unique. +' 3) Parameter names do not support attribute tags. Come up with different parameter names, instead. +' +'All source code in this file is licensed under a modified BSD license. This means you may use the code in your own +' projects IF you provide attribution. For more information, please visit http://photodemon.org/about/license/ +' +'*************************************************************************** + +Option Explicit +Option Compare Binary + +'Current parameter string. +Private m_ParamString As String + +Public Function getParamString() As String + getParamString = m_ParamString +End Function + +'If you obtain a parameter string from elsewhere (e.g. a PDI file), you can simple pass it as-is to this function +Public Sub setParamString(ByVal srcString As String) + m_ParamString = srcString +End Sub + +Public Sub Reset(Optional ByVal paramStringVersion As Double = 1#) + m_ParamString = "" & Trim$(Str(paramStringVersion)) & "" +End Sub + +Private Sub Class_Initialize() + + 'For now, this class does not add any extra XML around the parameters themselves. + ' It will, however, create a generic "version" tag at version 1.0. Functions are free to override this as necessary. + Me.Reset + +End Sub + +'If a function changes drastically enough, it is free to use the "created-by-default" version tag to adjust handling as necessary. +Public Function getParamVersion() As Double + + Dim versionString As String + If getParamValue("version", versionString) Then + getParamVersion = CDblCustom(versionString) + Else + getParamVersion = 0 + End If + +End Function + +Public Sub setParamVersion(Optional ByVal newVersion As Double = 1#) + updateParam "version", newVersion, True +End Sub + +'Simple check to see if a parameter exists +Public Function doesParamExist(ByRef paramName As String) As Boolean + + 'Make the parameter name XML-safe + paramName = getXMLSafeName(paramName) + + If InStr(1, m_ParamString, "<" & paramName & ">") Then + doesParamExist = True + Else + doesParamExist = False + End If + +End Function + +'Retrieve various type-specific parameters. Note that these ultimately wrap getParamValue; they simply cast the result explicitly. +Public Function GetBool(ByVal paramName As String, Optional ByVal defaultReturn As Boolean = False) As Boolean + + Dim paramValue As String + If getParamValue(paramName, paramValue) Then + GetBool = CBool(Trim$(paramValue)) + Else + GetBool = defaultReturn + End If + +End Function + +Public Function GetByte(ByVal paramName As String, Optional ByVal defaultReturn As Byte = 0) As Byte + + Dim paramValue As String + If getParamValue(paramName, paramValue) Then + GetByte = CByte(Trim$(paramValue)) + Else + GetByte = defaultReturn + End If + +End Function + +Public Function GetInteger(ByVal paramName As String, Optional ByVal defaultReturn As Integer = 0) As Integer + + Dim paramValue As String + If getParamValue(paramName, paramValue) Then + GetInteger = CInt(CDblCustom(Trim$(paramValue))) + Else + GetInteger = defaultReturn + End If + +End Function + +Public Function GetLong(ByVal paramName As String, Optional ByVal defaultReturn As Long = 0) As Long + + Dim paramValue As String + If getParamValue(paramName, paramValue) Then + GetLong = CLng(CDblCustom(Trim$(paramValue))) + Else + GetLong = defaultReturn + End If + +End Function + +Public Function GetSingle(ByVal paramName As String, Optional ByVal defaultReturn As Single = 0#) As Single + + Dim paramValue As String + If getParamValue(paramName, paramValue) Then + GetSingle = CDblCustom(Trim$(paramValue)) + Else + GetSingle = defaultReturn + End If + +End Function + +Public Function GetDouble(ByVal paramName As String, Optional ByVal defaultReturn As Double = 0#) As Double + + Dim paramValue As String + If getParamValue(paramName, paramValue) Then + GetDouble = CDblCustom(Trim$(paramValue)) + Else + GetDouble = defaultReturn + End If + +End Function + +Public Function GetString(ByVal paramName As String, Optional ByVal defaultReturn As String = "") As String + + Dim paramValue As String + If getParamValue(paramName, paramValue) Then + GetString = paramValue + Else + GetString = defaultReturn + End If + +End Function + +Public Function GetVariant(ByVal paramName As String, Optional ByVal defaultReturn As Variant = Empty) As Variant + + Dim paramValue As String + If getParamValue(paramName, paramValue) Then + GetVariant = CVar(paramValue) + Else + GetVariant = defaultReturn + End If + +End Function + +'Given a parameter name, fill a user-supplied string with the parameter value. +' Returns TRUE if parameter exists; FALSE otherwise. +Private Function getParamValue(ByVal paramName As String, ByRef dstString As String) As Boolean + + 'Make the parameter name XML-safe + paramName = getXMLSafeName(paramName) + + Dim tagStart As Long, tagEnd As Long + tagStart = InStr(1, m_ParamString, "<" & paramName & ">") + + 'If the opening tag was found, we also need to find the closing tag. + If tagStart > 0 Then + + tagEnd = InStr(tagStart, m_ParamString, "") + + 'If the closing tag exists, return everything between that and the opening tag + If tagEnd > tagStart Then + + 'Increment the tag start location by the length of the tag plus two (+1 for each bracket: <>) + tagStart = tagStart + Len(paramName) + 2 + + If tagEnd > tagStart Then + dstString = Mid$(m_ParamString, tagStart, tagEnd - tagStart) + dstString = unDelimitParamValue(dstString) + getParamValue = True + Else + dstString = "" + getParamValue = False + End If + + Else + Debug.Print "WARNING: requested parameter (" & paramName & ") wasn't properly closed!" + dstString = "" + getParamValue = False + End If + + Else + dstString = "" + getParamValue = False + End If + +End Function + +'Blindly add a parameter to the master string. No special checks (e.g. duplicates) are applied; use updateParam if you need those. +Public Function addParam(ByVal paramName As String, ByVal paramValue As Variant) As Boolean + + 'Convert the parameter value into a string. We handle this manually to minimize the chance of locale issues. + Dim strParamValue As String + + If VarType(paramValue) = vbByte Then + strParamValue = Trim$(Str(paramValue)) + ElseIf VarType(paramValue) = vbInteger Then + strParamValue = Trim$(Str(paramValue)) + ElseIf VarType(paramValue) = vbLong Then + strParamValue = Trim$(Str(paramValue)) + ElseIf VarType(paramValue) = vbSingle Then + strParamValue = Trim$(Str(paramValue)) + ElseIf VarType(paramValue) = vbDouble Then + strParamValue = Trim$(Str(paramValue)) + ElseIf VarType(paramValue) = vbDecimal Then + strParamValue = Trim$(Str(paramValue)) + ElseIf VarType(paramValue) = vbCurrency Then + strParamValue = Trim$(Str(paramValue)) + ElseIf VarType(paramValue) = vbNull Then + strParamValue = Trim$(Str(0)) + ElseIf VarType(paramValue) = vbBoolean Then + strParamValue = Trim$(Str(paramValue)) + ElseIf VarType(paramValue) = vbString Then + strParamValue = paramValue + ElseIf VarType(paramValue) = vbDate Then + strParamValue = Format(paramValue, "yyyy-mm-dd h:mm:ss", vbSunday, vbFirstJan1) + + 'Pray for a correct implicit cast result + Else + strParamValue = paramValue + End If + + + 'Make the parameter name and value XML-safe + paramName = getXMLSafeName(paramName) + strParamValue = delimitParamValue(strParamValue) + + 'Build a string with the parameter name and value we were passed + Dim newParamEntry As String + newParamEntry = vbCrLf & "<" & paramName & ">" & strParamValue & "" + + 'Tack it onto the master string + m_ParamString = m_ParamString & newParamEntry + +End Function + +'Update a given parameter. If the parameter is not found, it will be added to the string. (Create-if-missing behavior can be toggled.) +Public Function updateParam(ByVal paramName As String, ByVal paramValue As String, Optional ByVal createIfMissing As Boolean = True) As Boolean + + 'Make the parameter name and value XML-safe + paramName = getXMLSafeName(paramName) + paramValue = delimitParamValue(paramValue) + + 'See if the parameter already exists + Dim paramLocation As Long + paramLocation = InStr(1, m_ParamString, "<" & paramName & ">") + + Dim topHalf As String, bottomHalf As String + + 'If the parameter already exists, just update its value in-place. + If (paramLocation > 0) Then + + 'Split the XML file into two halves: the half before the relevant tag, and the half after + Dim paramCloseLocation As Long + paramCloseLocation = InStr(paramLocation, m_ParamString, "") + splitStringIn2 m_ParamString, paramCloseLocation - 1, topHalf, bottomHalf + + 'The "topHalf" string now includes everything before the closing tag. Chop it off at the end of the start tag (e.g. after + ' the closing bracket), add the new contents, then add the bottom half of the original XML string. + m_ParamString = Left$(topHalf, paramLocation + Len(paramName) + 1) & paramValue & bottomHalf + + updateParam = True + + 'The parameter does not exist; add it contingent on createIfMissing + Else + + If createIfMissing Then + + 'Build a string with the parameter name and value we were passed + Dim newParamEntry As String + newParamEntry = vbCrLf & "<" & paramName & ">" & paramValue & "" + + 'Reassemble the primary string + m_ParamString = m_ParamString & newParamEntry + + updateParam = True + + Else + updateParam = False + End If + + End If + +End Function + +'Given a string and a position, split it into two strings at that position +Private Function splitStringIn2(ByRef srcString As String, ByVal splitPosition As Long, ByRef dstFirstHalf As String, ByRef dstSecondHalf As String) + dstFirstHalf = Left$(srcString, splitPosition) + dstSecondHalf = Right$(srcString, Len(srcString) - splitPosition) +End Function + +'Given a string, replace any characters that are not allowed with underscores; this is used as a failsafe when adding +' new parameters to the master string. +Private Function getXMLSafeName(ByRef srcString As String) As String + + 'Remove any incidental white space before processing + getXMLSafeName = Trim(srcString) + + 'Create a string of valid numerical characters, based on the XML spec at http://www.w3.org/TR/1998/REC-xml-19980210.html#sec-common-syn + Dim validChars As String + validChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_:" + + 'Loop through the source string and replace any invalid characters with underscore + Dim i As Long + + For i = 1 To Len(getXMLSafeName) + If InStr(validChars, Mid$(getXMLSafeName, i, 1)) = 0 Then + getXMLSafeName = Left$(getXMLSafeName, i - 1) & "_" & Right$(getXMLSafeName, Len(getXMLSafeName) - i) + End If + Next i + +End Function + +'Given a parameter value string, make it XML-safe (e.g. replace "<" and ">" with HTML equivalents). +' Note that we don't have to delimit other chars because PD uses only a subset of XML functionality, by design. +Private Function delimitParamValue(ByVal srcString As String) As String + + If InStr(1, srcString, "<") Then srcString = Replace(srcString, "<", "<") + If InStr(1, srcString, ">") Then srcString = Replace(srcString, ">", ">") + + delimitParamValue = srcString + +End Function + +Private Function unDelimitParamValue(ByVal srcString As String) As String + + If InStr(1, srcString, "<") Then srcString = Replace(srcString, "<", "<") + If InStr(1, srcString, ">") Then srcString = Replace(srcString, ">", ">") + + unDelimitParamValue = srcString + +End Function + +'A custom CDbl function that accepts both commas and decimals as a separator; this is important when moving floating-point data, +' represented as strings, between locales. +Private Function CDblCustom(ByVal srcString As String) As Double + + 'Replace commas with periods + If InStr(1, srcString, ",") > 0 Then srcString = Replace(srcString, ",", ".") + + 'We can now use Val() to convert to Double + If IsNumberLocaleUnaware(srcString) Then + CDblCustom = Val(srcString) + Else + CDblCustom = 0 + End If + +End Function diff --git a/Classes/pdXML.cls b/Classes/pdXML.cls index a65144970e..18572a1ec8 100644 --- a/Classes/pdXML.cls +++ b/Classes/pdXML.cls @@ -447,8 +447,8 @@ End Function 'Given a string and a position, split it into two strings at that position Private Function splitStringIn2(ByRef srcString As String, ByVal splitPosition As Long, ByRef dstFirstHalf As String, ByRef dstSecondHalf As String) - dstFirstHalf = Left(srcString, splitPosition) - dstSecondHalf = Right(srcString, Len(srcString) - splitPosition) + dstFirstHalf = Left$(srcString, splitPosition) + dstSecondHalf = Right$(srcString, Len(srcString) - splitPosition) End Function 'Once a valid XML file has been loaded, we need to see if it contains valid XML data for the current operation. The client can diff --git a/PhotoDemon.vbp b/PhotoDemon.vbp index ce19be9d98..e14bf25653 100644 --- a/PhotoDemon.vbp +++ b/PhotoDemon.vbp @@ -292,6 +292,7 @@ Class=pdGraphicsPen; Classes\pdGraphicsPen.cls UserControl=Controls\penSelector.ctl Form=Forms\VBP_DialogPenSettings.frm UserControl=Controls\pdComboBox_Hatch.ctl +Class=pdParamXML; Classes\pdParamXML.cls ResFile32="Resources\PD_icons.RES" IconForm="FormMain" Startup="Sub Main" @@ -305,7 +306,7 @@ Description="PhotoDemon Photo Editor" CompatibleMode="0" MajorVer=6 MinorVer=7 -RevisionVer=306 +RevisionVer=307 AutoIncrementVer=1 ServerSupportFiles=0 VersionComments="Copyright 2000-2015 Tanner Helland - photodemon.org"