Russian Qt Forum
Сентябрь 30, 2024, 22:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QFileIconProvider не различает small и large иконки (Win)  (Прочитано 6634 раз)
spleenjack
Гость
« : Октябрь 29, 2008, 14:44 »

Вчера обнаружил странное поведение QDirModel/QFileSystemModel.

Вот как отображаются маленькие иконки при первом просмотре файлов с таким типом - см. аттач #1
И вот как после изменения порядка сортировки - см. аттач #2

Похоже на то, что у файла определенного типа, для которого еще не получена иконка - показывается нормальная small иконка.
Для всех последующих файлов того же типа - уже large иконка, уменьшенная до размеров строки.

Начал копаться в коде, и похоже нашел вот какой баг в QFileIconProvider.cpp:

Код:
QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const

...

    QPixmap pixmap;
    QPixmapCache::find(key, pixmap);

    if (!pixmap.isNull()) {
        retIcon.addPixmap(pixmap);
        if (QPixmapCache::find(key + QLatin1Char('l'), pixmap))
            retIcon.addPixmap(pixmap);
        return retIcon;
    }

...

    //Get the small icon
#ifndef Q_OS_WINCE
    val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
                        sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS);
    if (val) {
        pixmap = convertHIconToPixmap(info.hIcon);
        if (!pixmap.isNull()) {
            retIcon.addPixmap(pixmap);
            if (!key.isEmpty())
                QPixmapCache::insert(key, pixmap);
        }
        DestroyIcon(info.hIcon);
    }

...

    //Get the big icon
#ifndef Q_OS_WINCE
    val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
                        sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS);
    if (val) {
        pixmap = convertHIconToPixmap(info.hIcon);
        if (!pixmap.isNull()) {
            retIcon.addPixmap(pixmap);
            if (!key.isEmpty())
                QPixmapCache::insert(key, pixmap);
        }
        DestroyIcon(info.hIcon);
    }

Я не силен в цпп, но похоже на то, что сначала идет запрос к кешу по ключу key. Ничего там не найдя, происходит получение small иконки, которая добавляется как pixmap в retIcon и сам pixmap пихается в кеш. Дальше, тоже самое делается для large иконки, при этом заменяя в кеше pixmap на новый, большой. И возвращается retIcon, из которой берется (видимо) первый добавленный pixmap.

А вот при повторном запросе на иконку файла с типом, для которого иконка уже есть в кеше, возвращается сразу же та, которую туда последнюю положили, т.е. large.

Кто может, проверьте пожалуйста, такое ли и у вас поведение. Можно просто запусить examples\itemviews\dirview.
Версия Qt 4.4.3.

Я попробовал просто удалить ту часть кода, которая получает large иконку и перекомплил либу - и иконки стали нормальными. По-крайней мере, маленькие.

Имхо, в функу getWinIcon нужно добавить параметр, в котором можно указывать, какого размера иконка нужна. И соответственно, все юзающие его классы переписывать. Но это уже к тролям.
« Последнее редактирование: Октябрь 29, 2008, 15:00 от spleenjack » Записан
KADABRA
Гость
« Ответ #1 : Октябрь 29, 2008, 23:34 »

Цитировать
Кто может, проверьте пожалуйста, такое ли и у вас поведение.
Есть, версия та-же (4.4.2), Виста.

Похоже ошибка закралась во вторую строку
                QPixmapCache::insert(key, pixmap);
Должно быть
                QPixmapCache::insert(key + QLatin1Char('l'), pixmap);
Записан
ритт
Гость
« Ответ #2 : Октябрь 30, 2008, 01:56 »

заглянул в сорцы - действительно, похоже на недочёт копипаста Улыбающийся
создавайте таску в трекере. весьма желательно будет приложить к таске патчик.
ошибка примитивная и на функционал не влияет - большая вероятность того, что исправят уже в ближайшем минорном релизе.
а до тех пор можно подправить самостоятельно (и пересобрать Qt) Улыбающийся
Записан
spleenjack
Гость
« Ответ #3 : Октябрь 30, 2008, 18:52 »

Спасибо, и правда добавление QLatin1Char('l') помогло.
Отписал в task-tracker.
Записан
ритт
Гость
« Ответ #4 : Октябрь 30, 2008, 19:00 »

отпишись и здесь, как ответят, гут?
Записан
spleenjack
Гость
« Ответ #5 : Октябрь 30, 2008, 19:11 »

отпишись и здесь, как ответят, гут?
Ок. А насколько быстро они реагируют?
Записан
ритт
Гость
« Ответ #6 : Октябрь 30, 2008, 19:18 »

скоро узнаешь Улыбающийся
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #7 : Октябрь 30, 2008, 19:25 »

мне дважды в течении дня, отвечали, а вот последний раз несколько дней ждал (тут)
Записан

Юра.
ритт
Гость
« Ответ #8 : Октябрь 30, 2008, 20:51 »

не забывайте, что сейчас проходят devdays Улыбающийся
Записан
spleenjack
Гость
« Ответ #9 : Октябрь 31, 2008, 15:27 »

В 13:22 пришло письмо:

Цитировать
Thank you for reporting this issue, and for the suggested fix.

I was able to reproduce this here so I have created a task for our
development team to look into this issue. The ID for this task is:
233473.

You can use this ID to track the status of this task online:

http://www.trolltech.com/developer/task-tracker

Вот тикет: http://trolltech.com/developer/task-tracker/index_html?method=entry&id=233473
Записан
shadone
Гость
« Ответ #10 : Октябрь 31, 2008, 16:20 »

Исправлено. спасибо за сообщение об ошибке с патчем.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.048 секунд. Запросов: 23.