Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: spleenjack от Октябрь 29, 2008, 14:44



Название: QFileIconProvider не различает small и large иконки (Win)
Отправлено: 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 нужно добавить параметр, в котором можно указывать, какого размера иконка нужна. И соответственно, все юзающие его классы переписывать. Но это уже к тролям.


Название: Re: QFileIconProvider не различает small и large иконки (Win)
Отправлено: KADABRA от Октябрь 29, 2008, 23:34
Цитировать
Кто может, проверьте пожалуйста, такое ли и у вас поведение.
Есть, версия та-же (4.4.2), Виста.

Похоже ошибка закралась во вторую строку
                QPixmapCache::insert(key, pixmap);
Должно быть
                QPixmapCache::insert(key + QLatin1Char('l'), pixmap);


Название: Re: QFileIconProvider не различает small и large иконки (Win)
Отправлено: ритт от Октябрь 30, 2008, 01:56
заглянул в сорцы - действительно, похоже на недочёт копипаста :)
создавайте таску в трекере. весьма желательно будет приложить к таске патчик.
ошибка примитивная и на функционал не влияет - большая вероятность того, что исправят уже в ближайшем минорном релизе.
а до тех пор можно подправить самостоятельно (и пересобрать Qt) :)


Название: Re: QFileIconProvider не различает small и large иконки (Win)
Отправлено: spleenjack от Октябрь 30, 2008, 18:52
Спасибо, и правда добавление QLatin1Char('l') помогло.
Отписал в task-tracker.


Название: Re: QFileIconProvider не различает small и large иконки (Win)
Отправлено: ритт от Октябрь 30, 2008, 19:00
отпишись и здесь, как ответят, гут?


Название: Re: QFileIconProvider не различает small и large иконки (Win)
Отправлено: spleenjack от Октябрь 30, 2008, 19:11
отпишись и здесь, как ответят, гут?
Ок. А насколько быстро они реагируют?


Название: Re: QFileIconProvider не различает small и large иконки (Win)
Отправлено: ритт от Октябрь 30, 2008, 19:18
скоро узнаешь :)


Название: Re: QFileIconProvider не различает small и large иконки (Win)
Отправлено: lit-uriy от Октябрь 30, 2008, 19:25
мне дважды в течении дня, отвечали, а вот последний раз несколько дней ждал (тут (http://www.forum.crossplatform.ru/index.php?showtopic=1528))


Название: Re: QFileIconProvider не различает small и large иконки (Win)
Отправлено: ритт от Октябрь 30, 2008, 20:51
не забывайте, что сейчас проходят devdays :)


Название: Re: QFileIconProvider не различает small и large иконки (Win)
Отправлено: spleenjack от Октябрь 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


Название: Re: QFileIconProvider не различает small и large иконки (Win)
Отправлено: shadone от Октябрь 31, 2008, 16:20
Исправлено. спасибо за сообщение об ошибке с патчем.