Seite 1 von 2

Problem mit OpenFileRequester

Verfasst: 26.03.2009 02:44
von Crawler
Und wieder gibts etwas Code von mir. Ich habe den Auftrag bekommen, ein kleines Tool zu programmieren. Dieses soll doppelte Leerzeichen im Dateinamen eines PDF-Dokumentes eliminieren. Prinzipiell funktioniert das Ganze schon sehr ordentlich, zumindest wenn man "wenige" Dateien auf einmal umbenennen will. Anders sieht es aus, wenn ich im OpenFileRequester gleich ein- bis zweitausend Dateien wähle ("Strg+A" machts möglich) ;). Dann schreibt mir mein Programm hin, dass keine Dateien mit zwei Leerzeichen in Folge vorhanden wären. Dem ist aber definitiv so.
Also wie gesagt, bei 100 oder 200 Dateien funktioniert alles prima, nur bei volleren Ordnern nicht. Macke von Windows? Von PureBasic? Oder gar des Programmierers?

Code: Alles auswählen

Enumeration
  #Hauptfenster
  #Dateiliste
  #ButtonLaden
  #ButtonUmbenennen
  #ButtonEnde
  #Verlauf
EndEnumeration

Procedure.s NewName (Old.s)
  For i=1 To Len (Old.s)-1
    If Mid (Old.s, i, 1) =" " And Mid (Old.s, i+1, 1) =" "
      ; Zwei Leerzeichen?
    Else
      New.s+Mid (Old.s, i, 1)
    EndIf
  Next
  New.s+Right (Old.s,1)
  ProcedureReturn New.s
EndProcedure

OpenWindow (#Hauptfenster, 100, 100, 800, 650, "PDF Rename v0.1")
ListIconGadget (#Dateiliste, 10, 10, 600, 600, "alter Dateiname", 300)
AddGadgetColumn (#Dateiliste, 1, "neuer Dateiname", 1000)
ButtonGadget (#ButtonLaden, 620, 10, 170, 40, "Laden")
ButtonGadget (#ButtonUmbenennen, 620, 60, 170, 40, "Jetzt umbenennen")
ButtonGadget (#ButtonEnde, 620, 570, 170, 40, "Programm beenden")
ProgressBarGadget (#Verlauf, 620, 120, 170, 20, 0, 100)


Repeat
  EventID = WaitWindowEvent()
  If EventID = #PB_Event_Gadget
    Select EventGadget()
      Case #ButtonLaden
        ClearGadgetItems (#Dateiliste)
        File.s = OpenFileRequester("Bitte Dateien zum automatischen Umbenennen auswählen", GetCurrentDirectory (), "PDF (*.pdf)|*.pdf; *.PDF; *.Pdf", 0, #PB_Requester_MultiSelection)
        zaehl=0
        While File.s
          If File.s<>NewName.s (File.s)
            AddGadgetItem (#Dateiliste, -1, File.s+Chr(10)+NewName.s(File.s))
            zaehl+1
          EndIf  
          File.s=NextSelectedFileName ()
        Wend
        MessageRequester ("Information", "Es wurden "+Str(zaehl)+" Dateinamen gefunden, die 2 oder mehr Leerzeichen in Folge haben.")
      Case #ButtonUmbenennen
        SetGadgetAttribute (#Verlauf, #PB_ProgressBar_Maximum, CountGadgetItems (#Dateiliste))
        If CountGadgetItems (#Dateiliste)
          Wahl = MessageRequester ("Dateien umbenennen", "Soll der Vorgang jetzt ausgeführt werden?", #PB_MessageRequester_YesNo)
          If Wahl = #PB_MessageRequester_Yes
          Debug CountGadgetItems (#Dateiliste)
            For zaehl=1 To CountGadgetItems (#Dateiliste)
              Debug zaehl
              File.s=GetGadgetItemText (#Dateiliste, zaehl-1, 0)
              Debug File.s
              Debug NewName (File.s)
              If RenameFile (File.s, NewName (File.s))=0
                Debug "Error"
              EndIf  
              SetGadgetState (#Verlauf, zaehl)
            Next
            SetGadgetState (#Verlauf, 0)
            MessageRequester ("Information", Str(zaehl-1)+" Dateien umbenannt.")
          EndIf  
          ClearGadgetItems (#Dateiliste)
        Else
          MessageRequester ("Information", "Liste ist leer!")
        EndIf
      Case #ButtonEnde
        ende=1
    EndSelect    
  EndIf
Until EventID = #PB_Event_CloseWindow Or ende=1

Verfasst: 26.03.2009 13:11
von ralfschmitt
Warum gibst Du dem Programm nicht nur den Verzeichnispfad und lässt es die PDF-Dateien selbständig finden und umbenennen?

Verfasst: 26.03.2009 13:22
von Crawler
Gute Frage. :) Das hätte ich auch probieren können, ich hielt meine Version jedoch für intuitiver. Andererseits habe ich auch nicht die geringste Ahnung, wie ich die von dir angesprochene Variante umsetzen könnte. Gibts dazu ein paar Codezeilen? Ich stehe gerade wieder mächtig auf dem Schlauch...

[edit] Ich würde in dem Fall ein ExplorerTreeGadget verwenden, aber wie ich im gewählten Verzeichnis die einzelnen Dateien auslese stellt gerade noch eine Hürde dar.

Verfasst: 26.03.2009 13:36
von ts-soft

Code: Alles auswählen

Define Path.s = PathRequester("PDF space delimiter", "")
Define File.s, NFile.s
If Path
  If ExamineDirectory(0, Path, "*.pdf")
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) = #PB_DirectoryEntry_File
        File = DirectoryEntryName(0)
        If FindString(File, Space(2), 0)
          NFile.s = RemoveString(File, Space(2))
          RenameFile(Path + File, Path + NFile)
        EndIf
      EndIf
    Wend
    FinishDirectory(0)
  EndIf
EndIf

Verfasst: 26.03.2009 13:48
von Crawler
Erst mal ein dickes Dankeschön!

Gerade habe ich befüchtet, ich würd mir das mit dem Entfernen von 2 Leerzeichen unnötig kompliziert machen. Aber ich lösche in solch einem Fall ja nicht beide, sondern nur ein Leerzeichen. Aber das bildet schon mal ein sehr gutes Grundgerüst für die zweite Version.

Aber kann mir noch jemand erklären, warum der OpenFileRequester nicht richtig funktioniert?

Verfasst: 26.03.2009 13:54
von ts-soft
> Gerade habe ich befüchtet, ich würd mir das mit dem Entfernen von 2 Leerzeichen unnötig kompliziert machen

Code: Alles auswählen

Define Path.s = PathRequester("PDF space delimiter", "")
Define File.s, NFile.s
Define Pos
If Path
  If ExamineDirectory(0, Path, "*.pdf")
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) = #PB_DirectoryEntry_File
        File = DirectoryEntryName(0)
        If FindString(File, Space(2), 0)
          NFile.s = ReplaceString(File, Space(2), Space(1))
          RenameFile(Path + File, Path + NFile)
        EndIf
      EndIf
    Wend
    FinishDirectory(0)
  EndIf
EndIf
Du hast!
MultiSelect hat nur eine bestimmte Puffergröße, da passen nicht
unendlich viele Namen rein. In PB 4.20 gabs da glaub ich einen
diesbezüglichen Bug, ob das Limit aufgehoben ist kann ich nicht sagen.

Verfasst: 26.03.2009 14:06
von Crawler
ts-soft hat geschrieben: Du hast!
Das finde ich jetzt aber gemein! ;) So sieht man zumindest, dass auch andere Wege nach Rom führen. Einen Laufzeitvergleich unserer beiden Ansätze sollten wir jetzt besser nicht anstellen, sonst stehe ich ja noch schlechter da. :roll:
Aber hey, hab ich doch zumindest noch einen kleinen Bug in der 4.30er Version wiederentdeckt.

Verfasst: 26.03.2009 14:08
von Kaeru Gaman
ich glaube nicht dass das ein Bug in PB ist.

Verfasst: 26.03.2009 14:15
von ts-soft
Man könnte das entfernen des zweiten Spaces beschleunigen, aber nicht in
dem man andere Stringfunktionen verwendet, so wie in Deiner Procedure,
da muß man schon mit Pointern direkt im Stringspeicher arbeiten.

Das wäre aber mehr als Zeitverschwendung, weil der Zeitfaktor des
RemoveString im Zusammenhang mit den Fileoperationen garnicht ins
Gewicht fällt :wink:

Verfasst: 26.03.2009 14:17
von Crawler
Kaeru Gaman hat geschrieben:ich glaube nicht dass das ein Bug in PB ist.
Sondern? Programmiertechnisches Versagen hatte ich anfangs auch nicht ganz ausgeschlossen.
Zum Stand der Dinge: Mein Auftraggeber ist erst mal sehr angetan von "meinen"=euren Programmierfähigkeiten. Nun sollen die Dateien zusätzlich noch nach einem anderen Schema umbenannt werden. :roll: Immer diese Extrawünsche.