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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [Решено] Буфер обмена и Google Chrome  (Прочитано 10294 раз)
andrew.k
Гость
« : Май 03, 2012, 13:01 »

Код
C++ (Qt)
       QClipboard *clipboard = QApplication::clipboard();
       QMimeData * mimeData = new QMimeData();
 
       QTextDocumentFragment fragment = textEdit->textCursor().selection();
       QTextDocument docFrag;
       QTextCursor cur(&docFrag);
       cur.insertFragment(fragment);
...
       mimeData->setHtml(docFrag.toHtml());
       mimeData->setText(docFrag.toPlainText());
       clipboard->setMimeData(mimeData);
 
Вот кусок кода, который помещает в текст в буфер (форматированный и плейнтекст).
В результате опера, эксплорер, ворд и блокнот успешно могут вставить текст из буфера.
А хром почему-то не может вставить форматированный текст.
Проверял на gmail. Хотя из ворда в гмейл форматированный текст вставляется.

Что не хватает в коде? Почему так?
« Последнее редактирование: Май 04, 2012, 01:28 от andrew.k » Записан
V1KT0P
Гость
« Ответ #1 : Май 03, 2012, 15:23 »

Что не хватает в коде? Почему так?
Скопируй в буфер обмена из ворда и своей программы один и тот-же текст с одним и тем-же форматированием. И сравни в чем между ними разница.
Например скопированный текст Test жирный из ворда и вставленный в папку создал зип архив на 23 килобайта. Там внутри куча файлов. Это вроде один и тот-же текст в разных форматах. Вот и сравни пофайлово.
Записан
andrew.k
Гость
« Ответ #2 : Май 03, 2012, 15:44 »

Что не хватает в коде? Почему так?
Скопируй в буфер обмена из ворда и своей программы один и тот-же текст с одним и тем-же форматированием. И сравни в чем между ними разница.
Например скопированный текст Test жирный из ворда и вставленный в папку создал зип архив на 23 килобайта. Там внутри куча файлов. Это вроде один и тот-же текст в разных форматах. Вот и сравни пофайлово.
Вообще ничего не понял. Что пофайлово сравнивать? какой зип-архив? как из текста архив получился?  Непонимающий


Сравнил содержимое буфера обмена (программой InsideClipboard) скопированное из программы и из другого места.
Отличие в наличии формата CF_FORMAT, который определяет кодировку данных в буфере.
Причина проблемы qt-шная реализация буфера обмена не добавляет этот формат.
Видимо поэтому хром не зная какая кодировка не хочет вставлять.

Очевидно решением является добавление этого формата.
Средствами qt похоже это сделать невозможно или я не нашел.

Использовать Win API для добавления недостающей детали? как-то не хочется.
Записан
andrew.k
Гость
« Ответ #3 : Май 03, 2012, 22:18 »

Получается, что под виндой некорректно реализовано помещение html текста в буфер обмена.
Записан
Bepec
Гость
« Ответ #4 : Май 03, 2012, 22:36 »

Текст в архив - всё просто. docx ворда, это архив, содержищий файлы о стилях, тексте, форматировании и прочих прелестях.

Скорее всего проблема в типе. Насколько я помню, при помещении в буфер задаётся тип данных (не в Qt, а в браузерах), исходя из которого собственно и происходит преобразование. Советую просто посмотреть в эту сторону.
Записан
andrew.k
Гость
« Ответ #5 : Май 03, 2012, 23:52 »

Текст в архив - всё просто. docx ворда, это архив, содержищий файлы о стилях, тексте, форматировании и прочих прелестях.
но при чем тут все это?
Скорее всего проблема в типе. Насколько я помню, при помещении в буфер задаётся тип данных (не в Qt, а в браузерах), исходя из которого собственно и происходит преобразование. Советую просто посмотреть в эту сторону.
Я уже понял, в чем проблема, как пойму как её решить отпишу сюда.
Записан
andrew.k
Гость
« Ответ #6 : Май 04, 2012, 01:27 »

Эпиграф.
- Вот за это я и ненавижу кошек.
- Ты просто не умеешь их готовить.

Глава 1.
Если посмотреть внимательно на приведенный фрагмент кода, то видно, что там происходит копирование документа и его обработка.
И уже потом из него получается html. В этом и была проблема.

Вот описание формата HTML в буфере обмена windows.

Из описания видно, что в формате есть два поля в заголовке формата
Код
HTML
   StartFragment:140
   EndFragment:160

И маркеры внутри хтмл
Код
HTML
   <!--StartFragment -->
   <LI> The Fragment </LI>
   <!--EndFragment -->

Обе пары имеют одинаковое назначение: указать начало и конец необходимого фрагмента.
Т.к. выдрать кусок из хтмл нельзя из-за тегов, поэтому до начала фрагментов могут присутствовать другие теги (контекст фрагмента).

Глава 2.
Суть проблемы: получая html из объекта QTextDocument, в результате отсутствуют маркеры начала и конца фрагмента (т.к. это целый документ).
Что логично и нельзя воспринимать как баг. А получая html из QTextDocumentFragment, в результирующем html выставлены эти теги (маркеры <!-- -->). Они обрамляют фрагмент. Что тоже логично.
Теперь когда через QClipboard мы помещаем в буфер html полученный из документа, а не из фрагмента (как нужно делать), кто-то умный видя, что маркеры отсутствуют тупо добавляет их по краям, т.е. в начале и в конце.
При этом не обновляя значения в полях заголовка.
И итоге получается, что положение маркеров в html не соответствует значениям заданным в заголовке формата.

Видя такую картину Google Chrome как истинно кошерная программа отказывается принимать такой фрагмент, хотя всем другим это глубоко фиолетово  Смеющийся

Глава 3.
Решение:
Оно очень простое. Необходимо в документе выделить весь текст и получить выделенный фрагмент, а уже из него получать html.

Т.е. вот таким образом:
Код
C++ (Qt)
       cur.setPosition(0);
       cur.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
       fragment = cur.selection();
       mimeData->setData("text/html", fragDoc.toHtml("utf-8").toUtf8());

А вот пациент (видно, что значения в шапке не валидны, хотя скорее это маркеры неправильно расположены):
Код
HTML
Version:1.0
StartHTML:0000000105
EndHTML:0000001323
StartFragment:0000000127
EndFragment:0000001305
 
<!--StartFragment--><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Andrew</span> 12:33:48 demo text handId=92034024 </p></body></html><!--EndFragment-->

Занавес.
« Последнее редактирование: Май 04, 2012, 01:45 от andrew.k » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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