PDA

View Full Version : QDir Subclassing



Oleg
29th October 2007, 07:49
Hi everyone.
I'm looking for some information how QDir works.
I need to implement direct disk reading and filesystem browsing for FAT partitions and accessing to NTFS partitions through WinAPI.
So, my first question is, is there any reason in subclassing QDir or it'll be better to make my own new class?
Second one, which QDir's methods need to be implemented? For example, such methods like absolutePath (), makeAbsolute () or canonicalPath () rely on internal data (if yes, which? ) or always calling system functions? What about sorting? Will it work, if I provide correct QFileInfo objects? And how should I provide them?

Sorry, if there are too many mistakes, English isn't my motherlanguage and I haven't got enough practice.
Thanks for answers.

marcel
29th October 2007, 08:01
I need to implement direct disk reading and filesystem browsing for FAT partitions and accessing to NTFS partitions through WinAPI.

If you need more than QDir can offer then why don't you write your own class?
You should inherit QAbstractFileEngine. QDir is not meant for subclassing.

To see what WinAPI functions QDir uses you can always take a look at its sources.

Oleg
29th October 2007, 08:26
Thanks a lot, I have't noticed QAbstractFileEngine class.

As I've understood I should implement my own QAbstractFileEngine and QAbstractFileEngineHandler classes. And one question.

Documentation:

When you open a file, Qt chooses a suitable file engine by passing the file name from QFile or QDir through an internal list of registered file engine handlers.

I need access to whole file system, so I should use my own file name format, like fat:c:\windows or ntfs:d:\folder? Or something else? So, how can I say that some filesystem path must be processed using my file engine?

wysota
29th October 2007, 08:40
Something like that. But why do you do it in the first place? Can't you access the files with the regular file system access (QDir, QFile, ls, dir...)?

Oleg
29th October 2007, 09:00
Of course, I can :)
But it is my course work in the university. I should implement file manager with direct disk I/O for FAT FS and WinAPI interface for NTFS.
So, I'm looking for the simplest way.

In
virtual QAbstractFileEngine * create ( const QString & fileName ) const = 0
I check if fileName has my prefix and if so I return my new file engine. Is it right?
And in this way I can use all standart classes for filesystem access, like QDir, QDirModel, etc, without change, can't I?

wysota
29th October 2007, 09:05
I don't think this is the simplest way... Well, of course you CAN do it this way, but modifying the FS structures behind the system's back (I mean when the devices are mounted) is dangerous. As long as your file manager is read only you should be relatively safe, at least on uni-processor system. If you are on a unix like system, umounting the appropriate file systems is a must and then you can use the Qt abstract file engine. If you are on Windows (and I guess this is the case), you are walking on a thin line here, so think twice before doing anything.

Oleg
29th October 2007, 13:31
Of course, it's dangerous :)
But as I've said this is only an educational task and my program will never be used in the real life. So, I'm not afraid of crashing my virtual machine.

Thanks for answers.

Oleg
31st October 2007, 11:10
I have a problem while implementing my own QAbstractFileEngine.

So, I have a new class:


class cwNTFSFileEngine : public QAbstractFileEngine
{
public:
qint64 size() const;
bool isSequential() const;
bool isRelativePath() const;
QStringList entryList ( QDir::Filters filters, const QStringList &filterNames ) const;
FileFlags fileFlags ( FileFlags type = FileInfoAll ) const;
QString fileName ( FileName file = DefaultName ) const;
QDateTime fileTime ( FileTime time ) const;
Iterator *beginEntryList ( QDir::Filters filters, const QStringList &filterNames );
Iterator *endEntryList();
// Others methods are implemented, but return error values
};


And in


FileFlags cwNTFSFileEngine::fileFlags ( FileFlags type = FileInfoAll ) const
{
// File type detection
}


I get an error:
cwntfsfileengine.cpp:18: error: `FileFlags' does not name a type

I think there's a stupid bug in my, but I can't resolve it.

jpn
31st October 2007, 11:16
Prefix it with "QAbstractFileEngine::"


QAbstractFileEngine::FileFlags cwNTFSFileEngine::fileFlags ( QAbstractFileEngine::FileFlags type = FileInfoAll ) const
{
// File type detection
}

Oleg
31st October 2007, 12:03
Thanks for reply.

The correct solution:


QAbstractFileEngine::FileFlags cwNTFSFileEngine::fileFlags ( FileFlags type ) const
{
// code
}