Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Apr 19, 2024 03:32

Foren-Übersicht » Sonstiges » Projekte
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Mo Feb 22, 2010 22:32 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Servus,

ich habe eine Anwendung gebastelt mit der man Dateien katalogisieren kann.
Das kann man z.b. nutzen um eine Übersicht zu behalten über seine Festplatteninhalte.

Das Projekt ansich existiert schon seit 2002 und ist damals in Delphi geschrieben worden,
wurde dann von mir neugeschrieben in Lazarus.
Mittlerweile hab ich das Projekt nochmals neu und mit Plugin System in c# .NET 3.5 geschrieben.

Es gibt ein ähnliches kommerzielles Projekt mit dem namen "WhereIsIt".
Speedcat wurde von mir Entwickelt weil WIT definitiv mir zu teuer war
und für meine Bedürfnisse nicht gepasst hatte.

Speicherformat

Die Daten werden aktuell in SQLite gehalten, wobei Speedcat ein Datenbank Plugin modell besitzt,
mit der man auch andere Datei Datenbanken unterstützen könnte: Excel z.b. oder XML.

Addon fields

Um mehr Überblick über seine Inhalte zu behalten habe ich ein Plugin Modell eingeführt
indem sehr einfach neue Felder hinzufügt werden können.

Diese Felder können aktuell nur bei der Image Erstellung Automatisch mit Werten befüllt werden.
Manuelles befüllen ist noch nicht möglich, siehe Stand unten.

Trotzdem kann man einiges damit machen wie z.b. Hash felder die einen bei bedarf MD5, CRC, etc. generiert.
Der Sinn von Hashes muss man hier nicht weiter definieren. Das ist jedem selbst überlassen.

Stand

Aktuell kann man das Programm als "Fertig" einstufen aber enthält definitiv noch lang nicht alle features die ich haben will.
Das wäre z.b.

- Integration von neuen Dialogen / Forms per Plugin zur Grafischen Aufbereitung der Daten.
- Die Treeview soll auch Ordner darstellen können (Bisher gibts nur Catalogs -> Images)
- Integration von neuen Feldern in den vorhandenen Dialogen (Add/Edit image, Add/Edit catalog) zur manuellen Benutzereingabe oder befüllung mit "Addon fields". Dann kann man Speedcat auch als Objekt Katalogisierungverwenden, also nicht nur Daten, sondern auch Bücher z.b.

Hier mal 2 Screenshots: (Fun videos als Beispiel)

Bild
Bild

Sowie die Unterstützung für Ordner:

Bild

Der Download link:

Speedcat aktuelle version 1.2.4 (für Windows x86)
Speedcat aktuelle version 1.2.4 (für Windows x64 - Benötigt 64 bit)

Beide pakete benötigen das .NET Framework 3.5!

Viel spass damit,
Final


Zuletzt geändert von Finalspace am So Jul 18, 2010 11:33, insgesamt 9-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Mär 05, 2010 13:58 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Sorry leute,

Heul schon wieder ein bug

ich habe mal wieder was released wo sofort knallt wenn man eine neue Datenbank erzeugt :-(
Muss mir angewöhnen zumindest die Grundfunktionalitäten nochmal zu überprüfen bevor ich was release naja.

Die nächste Version welches sehr bald folgt, enthält ein paar neue Funktionen sowie diesen Bugfix.

Man kann in der nächsten Version beliebige User Interface Plugins hinzufügen und
z.b. seine eigene Grafische Ansicht bauen wenn einem die Treeview/Listview methode nicht gefällt.

Der Plugin ersteller müsste lediglich die Speedcat API verwenden die Speedcat bereit stellt,
sowie wissen das mittels Addon fields neue Felder und Tabellen erzeugt werden.
Ist nicht schwer, eventuell werd ich das ganze mal dokumentieren.

Zusätzlich gibt es nun auch die Möglichkeit vorhandene User Interface felder zu überschreiben.
Das kann man nutzen um z.b. den Image namen hochzählen zu lassen etc.

Bisher kann aber nur den Image namen überschreiben. Katalog name macht ebenfalls sinn, hab ich aber noch nicht eingebaut.

Um eigene User Interface felder zu haben, die man manuell befüllen kann, die man z.b. für eine Bücher verwaltung nutzen kann kann ich wohl erst umsetzten, wenn man Manuell "Daten" hinzufügen kann und man Kategorien/Ordner angegeben kann.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jun 28, 2010 10:58 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Es gibt neuigkeiten ;-)

Ich habe nun endlich die Unterstützung für Ordner eingebaut.

Bisher konnte man ja nur Kataloge anlegen, darin images und die images enthalten dann einfach alle Dateien die hinzugefügt worden sind, ohne Ordner.

Leider muss ich aber noch dazusagen, das ich die Ordner wohl nie in der DB gespeichert habe :-(
abe das natürlich nachgezogen und der "Files" Tabelle ein neues feld hinzugefügt "File Folder" und dieses wird nun beim Hinzufügen und Aktuallisieren eines Images geschrieben und enthält wie der name sagt, der Quell ordner der Datei.

Ich empfehle daher für diejenigen die das gerade aktuell nutzen, sobald die neue Version released ist, alle Images neu einzulesen (Update mit Clear files), dann sind auch ordner dabei und das browsen dürfte deutlichst verbessert sein :-)

Ein kleines wort noch dazu wie ich das gelöst habe:

Ich hatte mir anfangs überlegt, das ich eine Ordner tabelle mache und meine Files mit dieser Tabelle syncronisiere.
Aber da ich gemerkt habe, das für jedes image ein datenbank zugriff auf die Ordner tabelle zuviel habe ich diese idee vorworfen und das ganze anderst gelöst.

Ich erstelle beim laden eine sogenannte "Folder cache" tabelle im Speicher.
Darin lege ich alle Dateien / Sortiert bzw. Gruppiert nach Ordner und Image ab.
Ordner pfade werden aus dem neuen feld "File folder" geparsed und als baumstruktur abgespeichert.

Das generieren dieser Tabelle nimmt ein paar sekunden in anspruch, aber ich denke ich habe es so schnell gelöst wie irgendwie möglich.

Hier ist der ganze source der das möglich macht (Hashtables sind toll!!):

Code:

        class FileLoader
        {
            public Int64 ID;
            public Int64 ImageID;
            public String Filename;
            public String Folder;
        }

        class ImageCache
        {
            private List<FileLoader> aFiles;
            public ICollection<FileLoader> Files
            {
                get { return aFiles; }
            }

            public ImageCache()
            {
                aFiles = new List<FileLoader>();
            }

            public void Add(FileLoader entry)
            {
                aFiles.Add(entry);
            }
        }

        public class Folder
        {
            private Int64 iImageID;
            public Int64 ImageID
            {
                get { return iImageID; }
            }

            private String sFolderName;
            public String FolderName
            {
                get { return sFolderName; }
            }

            private String sFolderPath;
            public String FolderPath
            {
                get { return sFolderPath; }
                set { sFolderPath = value; }
            }

            private int iLevel;
            public int Level
            {
                get { return iLevel; }
            }

            private List<Int64> aFiles;
            public ICollection<Int64> Files
            {
                get { return aFiles; }
            }

            private Hashtable aSubFolders;
            public ICollection SubFolders
            {
                get { return aSubFolders.Values; }
            }

            public Folder(Int64 imgId, String folderName, int level, String folderPath)
            {
                iImageID = imgId;
                aFiles = new List<Int64>();
                sFolderName = folderName;
                iLevel = level;
                aSubFolders = new Hashtable();
                sFolderPath = folderPath;
            }

            public void Add(Int64 id)
            {
                aFiles.Add(id);
            }

            public void AddSubFolder(String key, Folder subfolder)
            {
                aSubFolders.Add(key, subfolder);
            }

            public Folder GetSubFolder(String key)
            {
                if (aSubFolders.ContainsKey(key))
                    return (Folder)aSubFolders[key];
                else
                    return null;
            }

            public void Clear()
            {
                aFiles.Clear();
                sFolderName = String.Empty;
                iLevel = 0;
                aSubFolders.Clear();
                sFolderName = String.Empty;
            }
        }

        private Hashtable cFolderCache;
        private void UpdateFolderCache(Int64 imageId, bool doNotClear)
        {
            // Clear folder cache
            if (!doNotClear)
                cFolderCache.Clear();

            // Generate image cache
            Hashtable imageCache = new Hashtable();
            using (SpeedcatDBQuery query = cDBManager.QueryFiles(imageId))
            {
                int queryCount = query.Execute(DBTables.Files, SpeedcatDBQuery.ModeQuery.Select);
                for (int i = 0; i < queryCount; i++)
                {
                    SpeedcatDBRow row = query.GetRow(i);
                    FileLoader fl = new FileLoader();
                    fl.ID = row.GetInt64(DBFieldNames.FileID);
                    fl.ImageID = row.GetInt64(DBFieldNames.FileImgID);
                    fl.Filename = row.GetString(DBFieldNames.FileFilename);
                    fl.Folder = row.GetString(DBFieldNames.FileFolder);
                    ImageCache imgCache;
                    if (!imageCache.ContainsKey(fl.ImageID))
                    {
                        imgCache = new ImageCache();
                        imageCache.Add(fl.ImageID, imgCache);
                    }
                    else
                        imgCache = (ImageCache)imageCache[fl.ImageID];
                    imgCache.Add(fl);
                }
            }

            // Loop through all images
            // Build also the real folder cache
            foreach (DictionaryEntry entry in imageCache)
            {
                Int64 imgid = (Int64)entry.Key;
                ImageCache imgCache = (ImageCache)entry.Value;

                Folder imageFolder;
                if (cFolderCache.ContainsKey(imgid))
                {
                    imageFolder = (Folder)cFolderCache[imgid];
                    imageFolder.Clear();
                }
                else
                {
                    imageFolder = new Folder(imgid, String.Empty, 0, String.Empty);
                    cFolderCache.Add(imgid, imageFolder);
                }

                String shortestPath = String.Empty;
                foreach (FileLoader fl in imgCache.Files)
                {
                    if (fl.Folder.Length < shortestPath.Length || shortestPath == String.Empty)
                        shortestPath = fl.Folder;
                }
                if (shortestPath != String.Empty)
                {
                    // Now cut of path from the file entries in the image
                    foreach (FileLoader fl in imgCache.Files)
                    {
                        String changedFolderPath = fl.Folder.Remove(0, shortestPath.Length);
                        String rootFolderPath = fl.Folder.Remove(fl.Folder.Length - changedFolderPath.Length, changedFolderPath.Length);
                        String folderName = String.Empty;
                        String[] split = changedFolderPath.Split(new char[] { '\' }, StringSplitOptions.RemoveEmptyEntries);

                        int level = split.Length;

                        if (split.Length == 0)
                        {
                            // Add root files to image folder
                            imageFolder.FolderPath = rootFolderPath;
                            imageFolder.Add(fl.ID);
                        }
                        else
                        {
                            Folder curFolder = imageFolder;
                            String curPath = rootFolderPath;
                            for (int i = 0; i < split.Length; i++)
                            {
                                String fname = split[i];
                                curPath += "\\" + fname;
                                Folder subFolder = curFolder.GetSubFolder(fname);
                                if (subFolder == null)
                                {
                                    subFolder = new Folder(imgid, fname, level, curPath);
                                    curFolder.AddSubFolder(fname, subFolder);
                                }
                                curFolder = subFolder;
                                if (i == split.Length - 1)
                                    curFolder.Add(fl.ID);
                            }
                        }
                    }
                }
            }
        }



Stay tuned,
Final


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jun 29, 2010 11:10 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
So neues release ist online.
Download link vom ersten post ist aktuallisiert.

Wichtig: Die Ordner-Unterstützung ist erst aktiv bei neuen Images!
Ich hatte leider in den vorherigen Versionen vergessen den Ordner in der DB mitzuspeichern :-(


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Jul 18, 2010 11:32 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Neue version (1.2.4) online:

- Kritische Start fehler beseitigt im falle eines Updates
- Bei Fehlern wird nun eine eigene Fehlerseite angezeigt mit details
- Nachdem hinzufügen eines Images wird ein kurzer Sound abgespielt, damit man weiss dass es ist fertig ^^
- Neues feld für files hinzufügt (RootPath)
- Bugfix für Verzeichnis unterstützung (RootPath wird verwendet zum speichern des selektierenden Pfads vom Image dialog)
- Bugfix für UNC pfad dateien

Links sind aktuallisiiert.

Verzeichnis unterstützung:

Ab speedcat version 1.2.4 wird der Ausgewählte Pfad für jedes neue Image gespeichert. Ältere images enthalten diesen Pfad logischerweise nicht.

Ist der dieser Pfad leer, dann wird das erste Verzeichnis eines Pfad als Start pfad verwendet, ansonsten wird das Verzeichnis als Startpfad verwendet was gespeichert wurde.

Image hinzufügen Sound:

Wenn jemand es benötigt das man den Sound für das hinzugefügte Image abschalten oder ändern möchte, dann melden.

Bisher ist der sound statisch als resource eingebunden, könnte aber theoretisch den sound wählbar machen, wäre kein problem.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Foren-Übersicht » Sonstiges » Projekte


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 54 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.190s | 19 Queries | GZIP : On ]