9.3. Расширенные возможности буфера обмена.

Большинство приложений используют внутренние механизмы Qt, при работе с буфером обмена. Например, класс QTextEdit включает в себя поддержку комбинаций клавиш Ctrl+X, Ctrl+C и Ctrl+V, которые соответствуют слотам cut(), copy() и paste(). В результате этого, от программиста не требуется написания специального кода, отвечающего за работу с буфером обмена.

При написании собственных классов, вы можете получить доступ к буферу обмена с помощью функции QApplication::clipboard(), которая возвращает указатель на объект класса QClipboard. Работа с буфером обмена на удивление проста и незатейлива! Чтобы поместить в него данные нужно лишь вызвать метод setText(), setImage() или setPixmap(). Чтобы получить данные из буфера -- text(), image() или pixmap(). В Главе 4 мы уже пробовали работать с буфером обмена, при разработке приложения Spreadsheet.

Однако, в некоторых случаях, встроенной поддержки буфера обмена может оказаться недостаточно. Например, может потребоваться обеспечить поддержку данных, которые не являются ни текстом, ни рисунком. Или, с целью повышения совместимости с другими приложениями, необходимо будет организовать обмен данными в нескольких форматах. Проблема очень напоминает то, с чем мы уже столкнулись чуть выше, поэтому и решение ее практически аналогичное: необходимо создать дочерний класс от QMimeSource и перекрыть методы родительского класса format() и encodedData()..

Если в приложение включена поддержка механизма "drag and drop", то вы можете просто использовать уже существующий потомок класса QDragObject, помещая объекты этого типа в буфер обмена, вызовом setData(). Поскольку QDragObject ведет свою родословную от QMimeSource, а буфер обмена умеет взаимодействовать с классом QMimeSource, то все будет работать без особых проблем.

Рассмотрим на примере, как можно реализовать функцию copy() для потомка класса QTable:

void MyTable::copy() { QApplication::clipboard()->setData(dragObject()); } В конце предыдущего раздела мы реализовали функцию dragObject(), которая возвращает CellDrag, предназначенный для хранения содержимого выделенных ячеек.

Чтобы извлечь данные из буфера обмена, необходимо обратиться к методу data(). Ниже приводится текст функции paste() для потомка класса QTable:

void MyTable::paste() { QMimeSource *source = QApplication::clipboard()->data(); if (CellDrag::canDecode(source)) { QString str; CellDrag::decode(source, str); performPaste(str); } } Функция performPaste() -- практически полный аналог функции Spreadsheet::paste() из Главы 4.

Это практически все, что необходимо для расширения возможностей при работе с буфером обмена.

Буфер обмена X11, предоставляет дополнительные возможности, которые недоступны в операционных системах Windows и Mac OS X. В X11, обычно имеется возможность вставки выделенной области, щелчком средней кнопки трехкнопочной мыши, благодаря наличию отдельного буфера "выделения". Если вы желаете добавить поддержку этого буфера обмена в свои виджеты, вам придется добавить дополнительный аргумент QClipboard::Selection во все вызовы, обращающиеся к буферу обмена. Например, вот как можно реализовать обработчик события mouseReleaseEvent() в текстовом редакторе, который должен поддерживать вставку блоков текста по щелчку средней кнопки мыши:

void MyTextEditor::mouseReleaseEvent(QMouseEvent *event) { QClipboard *clipboard = QApplication::clipboard(); if (event->button() == MidButton && clipboard->supportsSelection()) { QString text = clipboard->text(QClipboard::Selection); pasteText(text); } } На платформе X11 функция supportsSelection() возвращает true, на других -- false.