Results 1 to 7 of 7

Thread: File rename detection

  1. #1
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default File rename detection

    Hey guys,

    I've developped a class using QFileInfo to monitor a very large amount of files / folders.

    I didn't use QFileSystemWatcher because of its "file descriptors" limitation.

    Basically I have a callback that checks every folders.

    It's working pretty good.
    I detect File / folder modification, delete, create.

    My only issue is when a file gets renamed.
    Because the QFileInfo::lastModified() is not updated.

    Has anyone got a multi-platform way of detecting file renaming ?

    Thanks.

  2. #2
    Join Date
    Oct 2006
    Location
    New Delhi, India
    Posts
    2,467
    Thanks
    8
    Thanked 334 Times in 317 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: File rename detection

    You could compare the file name,,, cant you ???
    I dont know how you are checking for changes on file...but if you are storing previous info, you can check name too i guess instead of lastModified

  3. #3
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: File rename detection

    You cannot do that.

    Say you keep the QFileInfo of 3 files.
    You rename those 3 files.

    Your 3 QFileInfo are no longer valid.

    How do you know which is which ?

  4. #4
    Join Date
    Jan 2006
    Location
    Knivsta, Sweden
    Posts
    153
    Thanks
    30
    Thanked 13 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: File rename detection

    On unix at least, inode numbers remain unchanged after a rename within the filesystem. Otherwise I guess you'll have to keep a hash of the file contents.

  5. #5
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: File rename detection

    I guess we can conclude that:

    Multiplatform file renaming detection != trivial.

  6. #6
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: File rename detection

    Since I had a request,

    Here is my fileWatcher implementation.

    It uses Pimpl and some custom functions, it won't work out of the box.

    qkFileWatcher.h :
    Qt Code:
    1. #ifndef QKFILEWATCHER_H
    2. #define QKFILEWATCHER_H
    3.  
    4. #include <qkGlobalHeader.h>
    5.  
    6. // Qt includes
    7. #include <qobject>
    8. #include <qdateTime>
    9.  
    10. class qkFileWatcherPrivate;
    11.  
    12. class qkFileWatcher;
    13.  
    14. class QKCORE_EXPORT qkFileWatch
    15. {
    16. public: // Enums
    17. enum FileType
    18. {
    19. invalidType = 0,
    20. fileType,
    21. folderType
    22. };
    23.  
    24. public: // Ctor
    25. qkFileWatch(qkFileWatcher * watcher);
    26. qkFileWatch(const QString & path, qkFileWatcher * watcher);
    27. qkFileWatch(FileType type, const QString & path, qkFileWatcher * watcher);
    28. virtual ~qkFileWatch() {}
    29.  
    30. public: // Interface
    31. virtual void checkChange();
    32. void refreshDate();
    33.  
    34. protected: // Functions
    35. void request_fileModified(const QString parentPath, const QString fileName);
    36. void request_filesCreated(const QString parentPath, const QStringList fileNames);
    37. void request_filesDeleted(const QString parentPath, const QStringList fileNames);
    38.  
    39. void request_folderModified(const QString parentPath, const QString folderName);
    40. void request_foldersCreated(const QString parentPath, const QStringList folderNames);
    41. void request_foldersDeleted(const QString parentPath, const QStringList folderNames);
    42.  
    43. protected: // Variables
    44. QString mPath;
    45. QString mAbsolutePath;
    46. QString mName;
    47.  
    48. FileType mType;
    49.  
    50. QDateTime mLastModified;
    51.  
    52. qint64 mSize;
    53.  
    54. qkFileWatcher * mWatcher;
    55.  
    56. public: // Properties
    57. QString path() const;
    58. QString absolutePath() const;
    59. QString name() const;
    60.  
    61. bool isValid() const;
    62.  
    63. bool isFile() const;
    64. bool isDirectory() const;
    65. bool exists() const;
    66.  
    67. FileType type() const;
    68. };
    69.  
    70. class QKCORE_EXPORT qkFolderWatch : public qkFileWatch
    71. {
    72. public: // Ctor
    73. qkFolderWatch(const QString & path, qkFileWatcher * watcher);
    74.  
    75. public: // qkFileWatch interface reimplementation
    76. bool contains(const QString & path);
    77. virtual void checkChange();
    78.  
    79. private: // Functions
    80. void recurseDirectories();
    81. void checkDeleted();
    82.  
    83. int getFolderIndex_from_path(const QString & path);
    84. int getFileIndex_from_path(const QString & path);
    85.  
    86. private: // Variables
    87. QList<qkFileWatch> mFileWatchs;
    88. QList<qkFolderWatch> mFolderWatchs;
    89. };
    90.  
    91. class QKCORE_EXPORT qkFileWatcher : public QObject, public qkPrivatable
    92. {
    93. Q_OBJECT
    94. friend class qkFileWatch;
    95. friend class qkFolderWatch;
    96. private:
    97. QK_DECLARE_PRIVATE(qkFileWatcher);
    98.  
    99. public:
    100. qkFileWatcher(QObject * parent = 0);
    101. virtual ~qkFileWatcher();
    102.  
    103. public: // Interface
    104. void addPath(const QString & path);
    105. void removePath(const QString & path);
    106.  
    107. bool contains(const QString & path);
    108.  
    109. private slots:
    110. void onCheckForChange();
    111.  
    112. private: // Functions
    113. void request_folderModified(const QString parentPath, const QString folderName);
    114. void request_foldersCreated(const QString parentPath, const QStringList folderNames);
    115. void request_foldersDeleted(const QString parentPath, const QStringList folderNames);
    116.  
    117. void request_fileModified(const QString parentPath, const QString fileName);
    118. void request_filesCreated(const QString parentPath, const QStringList fileNames);
    119. void request_filesDeleted(const QString parentPath, const QStringList fileNames);
    120.  
    121. signals:
    122. // Folder
    123. void folderModified(const QString parentPath, const QString folderName);
    124. void foldersCreated(const QString parentPath, const QStringList folderNames);
    125. void foldersDeleted(const QString parentPath, const QStringList folderNames);
    126.  
    127. // File
    128. void fileModified(const QString parentPath, const QString fileName);
    129. void filesCreated(const QString parentPath, const QStringList fileNames);
    130. void filesDeleted(const QString parentPath, const QStringList fileNames);
    131. };
    132.  
    133. #endif // QKFILEWATCHER_H
    To copy to clipboard, switch view to plain text mode 

    qkFileWatcher.cpp part1 :

    Qt Code:
    1. #include "qkFileWatcher.h"
    2.  
    3. // Qt includes
    4. #include <qtimer>
    5.  
    6. // qk includes
    7. #include <qkFileController.h>
    8.  
    9. //=============================================================================
    10. // qkFileWatch
    11. //=============================================================================
    12.  
    13. qkFileWatch::qkFileWatch(FileType type, const QString & path, qkFileWatcher * watcher)
    14. {
    15. QFileInfo info(path);
    16.  
    17. mWatcher = watcher;
    18.  
    19. mPath = path;
    20. mAbsolutePath = info.absolutePath();
    21. mName = info.fileName();
    22. mType = type;
    23. mSize = -1;
    24.  
    25. refreshDate();
    26. }
    27.  
    28. qkFileWatch::qkFileWatch(const QString & path, qkFileWatcher * watcher)
    29. {
    30. QFileInfo info(path);
    31.  
    32. mWatcher = watcher;
    33.  
    34. mPath = path;
    35. mAbsolutePath = info.absolutePath();
    36. mName = info.fileName();
    37. mType = fileType;
    38. mSize = -1;
    39.  
    40. refreshDate();
    41. }
    42.  
    43. qkFileWatch::qkFileWatch(qkFileWatcher * watcher)
    44. {
    45. mWatcher = watcher;
    46.  
    47. mType = invalidType;
    48. mSize = -1;
    49.  
    50. refreshDate();
    51. }
    52.  
    53. //=============================================================================
    54.  
    55. void qkFileWatch::request_fileModified(const QString parentPath, const QString fileName)
    56. {
    57. mWatcher->request_fileModified(parentPath, fileName);
    58. }
    59.  
    60. void qkFileWatch::request_filesCreated(const QString parentPath, const QStringList fileNames)
    61. {
    62. mWatcher->request_filesCreated(parentPath, fileNames);
    63. }
    64.  
    65. void qkFileWatch::request_filesDeleted(const QString parentPath, const QStringList fileNames)
    66. {
    67. mWatcher->request_filesDeleted(parentPath, fileNames);
    68. }
    69.  
    70. //=============================================================================
    71.  
    72. void qkFileWatch::request_folderModified(const QString parentPath, const QString folderName)
    73. {
    74. mWatcher->request_folderModified(parentPath, folderName);
    75. }
    76.  
    77. void qkFileWatch::request_foldersCreated(const QString parentPath, const QStringList folderNames)
    78. {
    79. mWatcher->request_foldersCreated(parentPath, folderNames);
    80. }
    81.  
    82. void qkFileWatch::request_foldersDeleted(const QString parentPath, const QStringList folderNames)
    83. {
    84. mWatcher->request_foldersDeleted(parentPath, folderNames);
    85. }
    86.  
    87. //=============================================================================
    88.  
    89. void qkFileWatch::refreshDate()
    90. {
    91. QFileInfo info(mPath);
    92. if (info.exists() == false)
    93. {
    94. qkDebug("Deleted %s !", mPath.C_STR);
    95.  
    96. mSize = -1;
    97. mLastModified = QDateTime();
    98.  
    99. return;
    100. }
    101.  
    102. mSize = info.size();
    103. mLastModified = info.lastModified();
    104. }
    105.  
    106. /* virtual */ void qkFileWatch::checkChange()
    107. {
    108. QDateTime oldModified = mLastModified;
    109. qint64 oldSize = mSize;
    110.  
    111. refreshDate();
    112.  
    113. // We check both modified date and size for greater precision
    114. if (oldModified < mLastModified || oldSize != mSize)
    115. {
    116. if (mType == qkFileWatch::folderType)
    117. {
    118. request_folderModified(mAbsolutePath, mName);
    119. }
    120. else if (mType == qkFileWatch::fileType)
    121. {
    122. request_fileModified(mAbsolutePath, mName);
    123. }
    124. }
    125. }
    126.  
    127. //=============================================================================
    128.  
    129. QString qkFileWatch::path() const { return mPath; }
    130.  
    131. QString qkFileWatch::absolutePath() const { return mAbsolutePath; }
    132.  
    133. QString qkFileWatch::name() const { return mName; }
    134.  
    135. bool qkFileWatch::isValid() const
    136. {
    137. if (mType == invalidType) return false;
    138. else return true;
    139. }
    140.  
    141. bool qkFileWatch::isFile() const
    142. {
    143. if (mType == fileType) return true;
    144. else return false;
    145. }
    146.  
    147. bool qkFileWatch::isDirectory() const
    148. {
    149. if (mType == folderType) return true;
    150. else return false;
    151. }
    152.  
    153. bool qkFileWatch::exists() const
    154. {
    155. if (mSize == -1) return false;
    156. else return true;
    157. }
    158.  
    159. qkFileWatch::FileType qkFileWatch::type() const
    160. {
    161. return mType;
    162. }
    163.  
    164. //=============================================================================
    165. // qkFolderWatch
    166. //=============================================================================
    167.  
    168. qkFolderWatch::qkFolderWatch(const QString & path, qkFileWatcher * watcher)
    169. : qkFileWatch(folderType, path, watcher)
    170. {
    171. recurseDirectories();
    172. }
    173.  
    174. //=============================================================================
    175.  
    176. bool qkFolderWatch::contains(const QString & path)
    177. {
    178. for (int i = 0; i < mFolderWatchs.size(); i++)
    179. {
    180. if (mFolderWatchs[i].path() == path) return true;
    181. }
    182.  
    183. for (int i = 0; i < mFileWatchs.size(); i++)
    184. {
    185. if (mFileWatchs[i].path() == path) return true;
    186. }
    187.  
    188. return false;
    189. }
    190.  
    191. void qkFolderWatch::checkChange()
    192. {
    193. QDateTime oldModified = mLastModified;
    194.  
    195. qkFileWatch::checkChange();
    196.  
    197. // Checking all sub-directories
    198. for (int i = 0; i < mFolderWatchs.size(); i++)
    199. {
    200. mFolderWatchs[i].checkChange();
    201. }
    202.  
    203. // Note: on windows we have to check files even if the directory has not changed
    204. for (int i = 0; i < mFileWatchs.size(); i++)
    205. {
    206. mFileWatchs[i].checkChange();
    207. }
    208.  
    209. // Checking files only if the directory has been modified
    210. if (oldModified != mLastModified)
    211. {
    212. // Checking for deleted files
    213. checkDeleted();
    214.  
    215. // Recurse for new files
    216. recurseDirectories();
    217. }
    218. }
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: File rename detection

    qkFileWatcher.cpp part2:

    Qt Code:
    1. //=============================================================================
    2.  
    3. void qkFolderWatch::recurseDirectories()
    4. {
    5. QDir dir(mPath);
    6. QFileInfoList list = dir.entryInfoList();
    7. QStringList newFolders;
    8. QStringList newFiles;
    9.  
    10. foreach (QFileInfo info, list)
    11. {
    12. if (contains(info.filePath())) continue;
    13. if (info.fileName() == ".." || info.fileName() == ".") continue;
    14. if (info.isHidden()) continue;
    15.  
    16. if (info.isDir())
    17. {
    18. qkFolderWatch folder(info.filePath(), mWatcher);
    19. mFolderWatchs.push_back(folder);
    20.  
    21. newFolders += info.fileName();
    22. }
    23. else if (info.isFile())
    24. {
    25. qkFileWatch file(info.filePath(), mWatcher);
    26. mFileWatchs.push_back(file);
    27.  
    28. newFiles += info.fileName();
    29. }
    30. }
    31.  
    32. if (newFolders.size())
    33. {
    34. request_foldersCreated(mPath, newFolders);
    35. }
    36.  
    37. if (newFiles.size())
    38. {
    39. request_filesCreated(mPath, newFiles);
    40. }
    41. }
    42.  
    43. void qkFolderWatch::checkDeleted()
    44. {
    45. QStringList deletedFolders;
    46. QStringList deletedFiles;
    47.  
    48. for (int i = 0; i < mFolderWatchs.size(); i++)
    49. {
    50. if (mFolderWatchs[i].exists() == false)
    51. {
    52. deletedFolders += mFolderWatchs[i].name();
    53.  
    54. mFolderWatchs.removeAt(i);
    55. i = -1;
    56. }
    57. }
    58.  
    59. for (int i = 0; i < mFileWatchs.size(); i++)
    60. {
    61. if (mFileWatchs[i].exists() == false)
    62. {
    63. deletedFiles += mFileWatchs[i].name();
    64.  
    65. mFileWatchs.removeAt(i);
    66. i = -1;
    67. }
    68. }
    69.  
    70. if (deletedFolders.size())
    71. {
    72. request_foldersDeleted(mPath, deletedFolders);
    73. }
    74.  
    75. if (deletedFiles.size())
    76. {
    77. request_filesDeleted(mPath, deletedFiles);
    78. }
    79. }
    80.  
    81. //=============================================================================
    82.  
    83. int qkFolderWatch::getFolderIndex_from_path(const QString & path)
    84. {
    85. for (int i = 0; i < mFolderWatchs.size(); i++)
    86. {
    87. if (mFolderWatchs[i].path() == path) return i;
    88. }
    89. return -1;
    90. }
    91.  
    92. int qkFolderWatch::getFileIndex_from_path(const QString & path)
    93. {
    94. for (int i = 0; i < mFileWatchs.size(); i++)
    95. {
    96. if (mFileWatchs[i].path() == path) return i;
    97. }
    98. return -1;
    99. }
    100.  
    101. //=============================================================================
    102. // Private
    103. //=============================================================================
    104.  
    105. #include <qkGlobalHeader_p.h>
    106.  
    107. class qkFileWatcherPrivate : public qkPrivate
    108. {
    109. protected:
    110. QK_DECLARE_PUBLIC(qkFileWatcher);
    111.  
    112. public:
    113. qkFileWatcherPrivate(qkFileWatcher * p);
    114. void init();
    115.  
    116. private: // Functions
    117. void addPath(const QString & path);
    118. void removePath(const QString & path);
    119.  
    120. int getFolderIndex_from_path(const QString & path);
    121. int getFileIndex_from_path(const QString & path);
    122.  
    123. private: // Variables
    124. QTimer timer;
    125.  
    126. QList<qkFileWatch> fileWatchs;
    127. QList<qkFolderWatch> folderWatchs;
    128. };
    129.  
    130. qkFileWatcherPrivate::qkFileWatcherPrivate(qkFileWatcher * p)
    131. : qkPrivate(p)
    132. {
    133. }
    134.  
    135. void qkFileWatcherPrivate::init()
    136. {
    137. Q_Q(qkFileWatcher);
    138.  
    139. QObject::connect(&timer, SIGNAL(timeout()), q, SLOT(onCheckForChange()));
    140.  
    141. timer.start(100);
    142. }
    143.  
    144. //=============================================================================
    145.  
    146. void qkFileWatcherPrivate::addPath(const QString & path)
    147. {
    148. Q_Q(qkFileWatcher);
    149.  
    150. QFileInfo info(path);
    151.  
    152. if (info.isDir())
    153. {
    154. qkFolderWatch folder(path, q);
    155. folderWatchs.push_back(folder);
    156. }
    157. else
    158. {
    159. qkFileWatch file(path, q);
    160. fileWatchs.push_back(file);
    161. }
    162. }
    163.  
    164. void qkFileWatcherPrivate::removePath(const QString & path)
    165. {
    166. int index = getFolderIndex_from_path(path);
    167. if (index != -1) folderWatchs.removeAt(index);
    168.  
    169. index = getFileIndex_from_path(path);
    170. if (index != -1) fileWatchs.removeAt(index);
    171. }
    172.  
    173. //=============================================================================
    174.  
    175. int qkFileWatcherPrivate::getFolderIndex_from_path(const QString & path)
    176. {
    177. for (int i = 0; i < folderWatchs.size(); i++)
    178. {
    179. if (folderWatchs[i].path() == path) return i;
    180. }
    181. return -1;
    182. }
    183.  
    184. int qkFileWatcherPrivate::getFileIndex_from_path(const QString & path)
    185. {
    186. for (int i = 0; i < fileWatchs.size(); i++)
    187. {
    188. if (fileWatchs[i].path() == path) return i;
    189. }
    190. return -1;
    191. }
    192.  
    193. //=============================================================================
    194. // Ctor / dtor
    195. //=============================================================================
    196.  
    197. qkFileWatcher::qkFileWatcher(QObject * parent)
    198. : QObject(parent), qkPrivatable(new qkFileWatcherPrivate(this))
    199. {
    200. Q_D(qkFileWatcher);
    201. d->init();
    202. }
    203.  
    204. qkFileWatcher::~qkFileWatcher()
    205. {
    206. }
    207.  
    208. //=============================================================================
    209. // Interface
    210. //=============================================================================
    211.  
    212. void qkFileWatcher::addPath(const QString & path)
    213. {
    214. Q_D(qkFileWatcher);
    215.  
    216. if (contains(path)) return;
    217.  
    218. d->addPath(path);
    219. }
    220.  
    221. void qkFileWatcher::removePath(const QString & path)
    222. {
    223. Q_D(qkFileWatcher);
    224.  
    225. if (contains(path) == false) return;
    226.  
    227. d->removePath(path);
    228. }
    229.  
    230. bool qkFileWatcher::contains(const QString & path)
    231. {
    232. Q_D(qkFileWatcher);
    233.  
    234. for (int i = 0; i < d->folderWatchs.size(); i++)
    235. {
    236. if (d->folderWatchs[i].path() == path) return true;
    237. }
    238.  
    239. for (int i = 0; i < d->fileWatchs.size(); i++)
    240. {
    241. if (d->fileWatchs[i].path() == path) return true;
    242. }
    243.  
    244. return false;
    245. }
    246.  
    247. //=============================================================================
    248. // Private slots
    249. //=============================================================================
    250.  
    251. void qkFileWatcher::onCheckForChange()
    252. {
    253. Q_D(qkFileWatcher);
    254.  
    255. QFileInfo info;
    256.  
    257. for (int i = 0; i < d->fileWatchs.size(); i++)
    258. {
    259. d->fileWatchs[i].checkChange();
    260.  
    261. if (d->fileWatchs[i].exists() == false)
    262. {
    263. request_filesDeleted(d->fileWatchs[i].absolutePath(),
    264. QStringList() << d->fileWatchs[i].name());
    265.  
    266. d->fileWatchs.removeAt(i);
    267. i = -1;
    268. }
    269. }
    270.  
    271. for (int i = 0; i < d->folderWatchs.size(); i++)
    272. {
    273. d->folderWatchs[i].checkChange();
    274.  
    275. if (d->folderWatchs[i].exists() == false)
    276. {
    277. request_foldersDeleted(d->folderWatchs[i].absolutePath(),
    278. QStringList() << d->folderWatchs[i].name());
    279.  
    280. d->folderWatchs.removeAt(i);
    281. i = -1;
    282. }
    283.  
    284. }
    285. }
    286.  
    287. //=============================================================================
    288. // Private functions
    289. //=============================================================================
    290.  
    291. void qkFileWatcher::request_folderModified(const QString parentPath, const QString folderName)
    292. {
    293. qkDebug("Folder modified %s %s", parentPath.C_STR, folderName.C_STR);
    294.  
    295. emit folderModified(parentPath, folderName);
    296. }
    297.  
    298. void qkFileWatcher::request_foldersCreated(const QString parentPath, const QStringList folderNames)
    299. {
    300. foreach (QString name, folderNames)
    301. {
    302. qkDebug("Folder created %s %s", parentPath.C_STR, name.C_STR);
    303. }
    304.  
    305. emit foldersCreated(parentPath, folderNames);
    306. }
    307.  
    308. void qkFileWatcher::request_foldersDeleted(const QString parentPath, const QStringList folderNames)
    309. {
    310. foreach (QString name, folderNames)
    311. {
    312. qkDebug("Folder deleted %s %s", parentPath.C_STR, name.C_STR);
    313. }
    314.  
    315. emit foldersDeleted(parentPath, folderNames);
    316. }
    317.  
    318. //=============================================================================
    319.  
    320. void qkFileWatcher::request_fileModified(const QString parentPath, const QString fileName)
    321. {
    322. qkDebug("File modified %s %s", parentPath.C_STR, fileName.C_STR);
    323.  
    324. emit fileModified(parentPath, fileName);
    325. }
    326.  
    327. void qkFileWatcher::request_filesCreated(const QString parentPath, const QStringList fileNames)
    328. {
    329. foreach (QString name, fileNames)
    330. {
    331. qkDebug("File created %s %s", parentPath.C_STR, name.C_STR);
    332. }
    333.  
    334. emit filesCreated(parentPath, fileNames);
    335. }
    336.  
    337. void qkFileWatcher::request_filesDeleted(const QString parentPath, const QStringList fileNames)
    338. {
    339. foreach (QString name, fileNames)
    340. {
    341. qkDebug("File deleted %s %s", parentPath.C_STR, name.C_STR);
    342. }
    343.  
    344. emit filesDeleted(parentPath, fileNames);
    345. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Read binary from file
    By weldpua2008 in forum Newbie
    Replies: 2
    Last Post: 3rd April 2009, 23:50
  2. Set up the Qt4.3.2 with Visual Studio 2005
    By lamoda in forum Installation and Deployment
    Replies: 6
    Last Post: 30th January 2008, 06:51
  3. file renaming on windows
    By jdd81 in forum Qt Programming
    Replies: 9
    Last Post: 2nd October 2007, 19:41
  4. qt-3.3.8 fail in scratchbox
    By nass in forum Installation and Deployment
    Replies: 0
    Last Post: 25th May 2007, 15:21
  5. How to rename a file after opening ?
    By npc in forum Newbie
    Replies: 2
    Last Post: 1st June 2006, 13:36

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.