Mir scheint das Programm ist fertig...
(Es kann nichts weltbewegendes aber als Übung wars gut denke ich.) Ich habe alle Funktionen getestet und keine Fehler gefunden. Ich poste den Code mal hier und vielleicht hat jemand noch Verbesserungsvorschläge oder findet Fehler.
* Texte in Ascii, Unicode und UTF-8 einlesen, die Zeilenreihenfolge bearbeiten und wieder in eine Datei ausgeben
* Beim Bearbeiten kann es die Zeilen Sortieren (Aufsteigend, Aufsteigend NoCase, Absteigend, Absteigend NoCase, Zufällig anordnen oder die Reihenfolge nicht verändern)
* Dazu und in Kombination kann es Zeilen löschen (Doppelte, Doppelte NoCase oder keine doppelten Zeilen Löschen)
* Speedtestmodes mit 20 Durchläufen. Ein und auschaltbar wenn die Maus unten links im Formular in einem 20 Pixel hohen und breiten Bereich steht und man speedmode eingibt. Genauso ist es wieder ausschaltbar.
Code: Alles auswählen
EnableExplicit
#LoopsSpeedmodeMax =20
Structure TimerLog
All.i
ReadSource.i
Delete.i
Sort.i
Write.i
EndStructure
Structure DataList
OrigPos.i
DelRow.a
DataRow$
EndStructure
Global.i *LogEditorHandle, LastScrollTime
Define.TimerLog AllStat
Define.i *MainWindowHandle, *SourceButtonHandle, *SourceStringHandle, *TargetButtonHandle, *TargetStringHandle
Define.i *SortTextHandle, *SortComboBoxHandle, *DeleteTextHandle, *DeleteBlankRowsCheckboxHandle, *StartButtonHandle
Define.i *DeleteComboBoxHandle, *HiddenModeTextHandle, *ReadFileHandle, *WriteFileHandle, *RegexHandle
Define.i LoopsSpeedmode, Lines, MouseX, MouseY, x, EventID, StartTime, FirstStartTime, SpeedtestStartTime
Define.s HiddenModeKeys$, File$, LastRowContent$, Clipboard$
Define.a Speedmode, Result, StringCoding, SortStyle, DeleteStyle, DeleteBlankRows, Flags, DelBlank
Procedure Msg(Msg$,Type.a = 0)
Define.s Type$
If Not Type: Type$ = "Error" : Else : Type$ = "Message" : EndIf
MessageRequester(Type$, Type$+": " + Msg$, 0)
If Not Type : End : EndIf
EndProcedure
Procedure ChkCreated(*Handle.i, Type$, Action$ = "create")
If Not *Handle : Msg("Couldnt " + Action$ + " " + Type$) : End : EndIf
EndProcedure
Procedure WriteLog(LogEntry$, EndofLog.a = 0)
AddGadgetItem(*LogEditorHandle, -1, LogEntry$)
If (ElapsedMilliseconds() - LastScrollTime) > 100 Or EndofLog
SendMessage_(GadgetID(*LogEditorHandle),#EM_SCROLL,#SB_BOTTOM,0)
LastScrollTime = ElapsedMilliseconds()
EndIf
EndProcedure
Procedure In(ValueToCheck.i,ValueString$)
Define.i ValueCount, x
ValueCount = CountString(ValueString$,",") + 1
For x = 1 To ValueCount
If Val(StringField(ValueString$, x, ",")) = ValueToCheck
ProcedureReturn 1
EndIf
Next
ProcedureReturn 0
EndProcedure
Macro Float(Long)
((Long)*1.0)
EndMacro
;Creating Window and Gadgets
;-----------------------
*MainWindowHandle=OpenWindow(#PB_Any, 0, 0, 661, 180, "SortIt", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered)
ChkCreated(*MainWindowHandle,"Window")
*SourceButtonHandle = ButtonGadget(#PB_Any, 10, 10, 110, 25, "Choose Sourcefile")
*TargetButtonHandle = ButtonGadget(#PB_Any, 10, 45, 110, 25, "Choose Targetfile")
*SourceStringHandle = StringGadget(#PB_Any, 140, 10, 510, 25, "")
*TargetStringHandle = StringGadget(#PB_Any, 140, 45, 510, 25, "")
*LogEditorHandle = EditorGadget(#PB_Any, 10, 80, 250, 90, #PB_Editor_ReadOnly)
*SortTextHandle = TextGadget(#PB_Any, 270, 83, 80, 20, "Sort-Options:")
*SortComboBoxHandle = ComboBoxGadget(#PB_Any, 350, 80, 200, 20)
AddGadgetItem(*SortComboBoxHandle, -1, "Sort Ascending Case Sensitive")
AddGadgetItem(*SortComboBoxHandle, -1, "Sort Ascending Case Insensitive")
AddGadgetItem(*SortComboBoxHandle, -1, "Sort Descending Case Sensitive")
AddGadgetItem(*SortComboBoxHandle, -1, "Sort Descending Case Insensitive")
AddGadgetItem(*SortComboBoxHandle, -1, "Sort Randomly")
AddGadgetItem(*SortComboBoxHandle, -1, "No Change in Order")
SetGadgetState(*SortComboBoxHandle, 0)
*DeleteTextHandle = TextGadget(#PB_Any, 270, 113, 80, 30, "Delete-Options:")
*DeleteComboBoxHandle = ComboBoxGadget(#PB_Any, 350, 110, 200, 20)
AddGadgetItem(*DeleteComboBoxHandle, -1, "Delete Duplicate Rows Case Sensitive")
AddGadgetItem(*DeleteComboBoxHandle, -1, "Delete Duplicate Rows Case Insensitive")
AddGadgetItem(*DeleteComboBoxHandle, -1, "Dont Delete Duplicate Rows")
SetGadgetState(*DeleteComboBoxHandle, 2)
*DeleteBlankRowsCheckboxHandle = CheckBoxGadget(#PB_Any, 350, 137, 200, 20, "Delete Blank Rows")
*StartButtonHandle = ButtonGadget(#PB_Any, 570, 80, 80, 50, "START")
*HiddenModeTextHandle = TextGadget(#PB_Any, 570, 140, 80, 20, "")
SetGadgetColor(*HiddenModeTextHandle, #PB_Gadget_FrontColor, $0000FF)
Repeat
EventID = WaitWindowEvent()
;Switch for en- and disabling Speedtestmode
;-----------------------
If EventID = #WM_KEYDOWN
MouseX = WindowMouseX(*MainWindowHandle)
MouseY = WindowMouseY(*MainWindowHandle)
If MouseX >= 0 And MouseX <=20 And MouseY >= 160 And MouseY <= 180
HiddenModeKeys$ = Right(HiddenModeKeys$ + Chr(EventwParam()), 9)
If HiddenModeKeys$ = "SPEEDMODE"
If GetGadgetText(*HiddenModeTextHandle) = ""
SetGadgetText(*HiddenModeTextHandle, "Speedtestmode")
Speedmode = 1
Else
SetGadgetText(*HiddenModeTextHandle, "")
Speedmode = 0
EndIf
EndIf
Else
HiddenModeKeys$ = ""
EndIf
EndIf
If EventWindow() = *MainWindowHandle And EventID = #PB_Event_Gadget
If EventGadget() = *SourceButtonHandle
File$ = OpenFileRequester("Please choose the file to read from", "", "Text (*.txt)|*.txt;*.bat|All Files (*.*)|*.*", 0)
If File$
If FileSize(File$) = -2 : Msg("A directory cant be the source",1) : File$ = "" : EndIf
SetGadgetText(*SourceStringHandle,File$)
EndIf
EndIf
If EventGadget() = *TargetButtonHandle
File$ = OpenFileRequester("Please choose the file to write to", "", "Text (*.txt)|*.txt;*.bat|All Files (*.*)|*.*", 0)
If File$
If FileSize(File$) = -2 : Msg("A directory cant be the target",1) : File$ = "" : EndIf
SetGadgetText(*TargetStringHandle,File$)
EndIf
EndIf
If EventGadget() = *StartButtonHandle
Repeat
If FileSize(GetGadgetText(*SourceStringHandle)) = -1 : Msg("Sourcefile doesnt exist",1) : SetGadgetText(*SourceStringHandle,"") : Break : EndIf
If FileSize(GetGadgetText(*SourceStringHandle)) = -2 : Msg("Sourcefile cant be a directory",1) : SetGadgetText(*SourceStringHandle,"") : Break : EndIf
If FileSize(GetGadgetText(*TargetStringHandle)) = -2 : Msg("Targetfile cant be a directory",1) : SetGadgetText(*TargetStringHandle,"") : Break : EndIf
If FileSize(GetGadgetText(*TargetStringHandle)) >= 0 And Not Speedmode
Result = MessageRequester("Request", "Targetfile already exists. Overwrite?", #PB_MessageRequester_YesNo)
If Result = #PB_MessageRequester_No : Break : EndIf
EndIf
SetGadgetText(*LogEditorHandle, "")
NewList TimerLogList.TimerLog()
LoopsSpeedmode = 0
SpeedtestStartTime = ElapsedMilliseconds()
Repeat
LoopsSpeedmode + 1
*ReadFileHandle = ReadFile(#PB_Any, GetGadgetText(*SourceStringHandle))
*WriteFileHandle = CreateFile(#PB_Any, GetGadgetText(*TargetStringHandle))
If Not *ReadFileHandle : Msg("Couldnt open Sourcefile") : Break : EndIf
If Not *WriteFileHandle : Msg("Couldnt open Targetfile") : Break : EndIf
StringCoding = ReadStringFormat(*ReadFileHandle)
If Not (StringCoding = #PB_Ascii Or StringCoding = #PB_UTF8 Or StringCoding = #PB_Unicode)
Msg("Found unknown StringCoding. Cant work with it.",1)
Break
EndIf
AddElement(TimerLogList())
StartTime = ElapsedMilliseconds()
FirstStartTime = StartTime
SortStyle = GetGadgetState(*SortComboBoxHandle)
DeleteStyle = GetGadgetState(*DeleteComboBoxHandle)
DeleteBlankRows = GetGadgetState(*DeleteBlankRowsCheckboxHandle)
;Read in File Data
;-----------------------
NewList DataList.DataList()
If SortStyle = 4 : Dim *SourceFileContentListPointerArray(1000) : EndIf
Lines = 0
While Eof(*ReadFileHandle) = 0
If SortStyle = 4
If Lines % 1000 = 0
ReDim *SourceFileContentListPointerArray(Lines + 1000)
EndIf
*SourceFileContentListPointerArray(Lines) = AddElement(DataList())
Else
AddElement(DataList())
EndIf
DataList()\DataRow$ = ReadString(*ReadFileHandle,StringCoding)
DataList()\OrigPos = Lines
Lines + 1
Wend
If SortStyle = 4 : ReDim *SourceFileContentListPointerArray(Lines - 1) : EndIf
CloseFile(*ReadFileHandle)
TimerLogList()\Readsource = ElapsedMilliseconds() - StartTime
Select StringCoding
Case #PB_Ascii
Clipboard$ = "Ascii"
Case #PB_UTF8
Clipboard$ = "UTF8"
Case #PB_Unicode
Clipboard$ = "Unicode"
EndSelect
WriteLog(Str(Lines) + " Lines " + Clipboard$ + "-Data read in " + Str(TimerLogList()\Readsource) + " ms (" + StrF(Float(TimerLogList()\Readsource) / 1000,3) + " s)")
StartTime = ElapsedMilliseconds()
;First Handle the deletions
;-----------------------
If DeleteStyle = 0 Or DeleteStyle = 1.
If DeleteStyle = 1 : Flags = 2 : Else : Flags = 0 : EndIf
SortStructuredList(DataList(), Flags ,OffsetOf(DataList\DataRow$), #PB_Sort_String)
Lines = 0
LastRowContent$ = "@@@@@####*****@@@@"
ForEach DataList()
Lines + 1
If DataList()\DataRow$ = "" Or LastRowContent$ = ""
If DeleteBlankRows And DataList()\DataRow$ = ""
Lines - 1
EndIf
LastRowContent$ = DataList()\DataRow$
Continue
EndIf
If DeleteStyle = 0 And DataList()\DataRow$ = LastRowContent$
DataList()\DelRow = 1
Lines - 1
EndIf
If DeleteStyle = 1 And LCase(DataList()\DataRow$) = LCase(LastRowContent$)
DataList()\DelRow = 1
Lines - 1
EndIf
LastRowContent$ = DataList()\DataRow$
Next
EndIf
If DeleteStyle = 2 And DeleteBlankRows
Lines = 0
ForEach DataList()
Lines + 1
If DataList()\DataRow$ = "" : Lines - 1 : EndIf
Next
EndIf
TimerLogList()\Delete = ElapsedMilliseconds() - StartTime
WriteLog(Str(Lines) + " Lines left after Deletion in " + Str(TimerLogList()\Delete) + " ms (" + StrF(Float(TimerLogList()\Delete) / 1000,3) + " s)")
StartTime = ElapsedMilliseconds()
;Sorting
;-----------------------
Select SortStyle
Case 0, 1, 2, 3
Flags = 0
Select SortStyle
Case 1
Flags = 2
Case 2
Flags = 1
Case 3
Flags = 3
EndSelect
If Not ((SortStyle = 1 And DeleteStyle = 1) Or (SortStyle = 0 And DeleteStyle = 0)) ;Sort only needed when not already done
SortStructuredList(DataList(), Flags, OffsetOf(DataList\DataRow$), #PB_Sort_String)
EndIf
EndSelect
;Randomize
;-----------------------
If SortStyle = 4
For x = ArraySize(*SourceFileContentListPointerArray()) - 1 To 1 Step -1
;Must be random(x) and not x-1 otherwise the last element couldnt swap with itself and remain at the last position after shuffling
SwapElements(DataList(), *SourceFileContentListPointerArray(x), *SourceFileContentListPointerArray(Random(x)))
Next
EndIf
;Bring back the Row-Order from before when User didnt want to sort the list in any way
;-----------------------
If In(DeleteStyle,"0,1") And SortStyle = 5
SortStructuredList(DataList(), #PB_Sort_Ascending, OffsetOf(DataList\OrigPos), #PB_Sort_Integer)
EndIf
TimerLogList()\Sort = ElapsedMilliseconds() - StartTime
WriteLog(Str(Lines) + " Lines are sorted in " + Str(TimerLogList()\Sort) + " ms (" + StrF(Float(TimerLogList()\Sort) / 1000,3) + " s)")
WriteStringFormat(*WriteFileHandle,StringCoding)
Lines = 0
ForEach DataList()
If (DeleteBlankRows And DataList()\DataRow$ = "") Or DataList()\DelRow : Continue : EndIf
Lines + 1
WriteStringN(*WriteFileHandle, DataList()\DataRow$,StringCoding)
Next
CloseFile(*WriteFileHandle)
TimerLogList()\Write = ElapsedMilliseconds() - StartTime
WriteLog(Str(Lines) + " Lines written in " + Str(TimerLogList()\Write) + " ms (" + StrF(Float(TimerLogList()\Write) / 1000,3) + " s)")
TimerLogList()\All = ElapsedMilliseconds() - FirstStartTime
If Speedmode
WriteLog("Round " + Str(LoopsSpeedmode) + " of " + Str(#LoopsSpeedmodeMax) + " completely done in: " + Str(TimerLogList()\All) + " ms (" + StrF(Float(TimerLogList()\All) / 1000,3) + " s)" + #CRLF$ + "-----------------------")
Else
WriteLog("All done in: " + Str(TimerLogList()\All) + " ms (" + StrF(Float(TimerLogList()\All) / 1000,3) + " s)")
EndIf
If Speedmode And LoopsSpeedmode = #LoopsSpeedmodeMax
ClearStructure(@AllStat, TimerLog)
ForEach TimerLogList()
AllStat\All + TimerLogList()\All
AllStat\ReadSource + TimerLogList()\ReadSource
AllStat\Delete + TimerLogList()\Delete
AllStat\Sort + TimerLogList()\Sort
AllStat\Write + TimerLogList()\Write
Next
AllStat\All / #LoopsSpeedmodeMax
AllStat\ReadSource / #LoopsSpeedmodeMax
AllStat\Delete / #LoopsSpeedmodeMax
AllStat\Sort / #LoopsSpeedmodeMax
AllStat\Write / #LoopsSpeedmodeMax
WriteLog("Speedtest-Result: (" + Str(#LoopsSpeedmodeMax) + " Loops): " + #CRLF$ + "Read: " + Str(AllStat\ReadSource) + " ms on average" + #CRLF$ + "Delete: " + Str(AllStat\Delete) + " ms on average" + #CRLF$ + "Sort: " + Str(AllStat\Sort) + " ms on average" + #CRLF$ + "Write: " + Str(AllStat\Write) + " ms on average" + #CRLF$ + "Rounds done in: " + Str(AllStat\All) + " ms on average" + #CRLF$ + "Whole Speedtest took: " + Str(ElapsedMilliseconds() - SpeedtestStartTime) + " ms",1)
EndIf
Until LoopsSpeedmode = #LoopsSpeedmodeMax Or Not Speedmode
Until #True
EndIf
EndIf
Until EventID = #PB_Event_CloseWindow
Eine Verbesserungsmöglichkeit wäre noch eine Erwähnung von Nic, das Modell Model View Controller. Da muss ich aber erstmal schauen wie man das praktisch umsetzt.