29 #include <QTextCursor>
30 #include <QStackedWidget>
33 #include <QContextMenuEvent>
35 #include <QItemSelectionModel>
39 #include <kactioncollection.h>
41 #include <KApplication>
46 #include <akonadi/entitytreemodel.h>
47 #include <akonadi/item.h>
49 #include <KMime/Message>
57 Q_DECLARE_METATYPE(QTextDocument*)
59 Q_DECLARE_METATYPE(QTextCursor)
61 using namespace Akonadi;
65 actionCollection( 0 ),
66 allowAutoDecimal(false),
67 m_selectionModel( selectionModel )
69 setAcceptRichText(
true);
70 setWordWrapMode(QTextOption::WordWrap);
71 setCheckSpellingEnabled(
true);
72 setRichTextSupport( FullTextFormattingSupport
76 | SupportFormatPainting );
78 setFocusPolicy(Qt::StrongFocus);
80 connect( m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(selectionChanged(QItemSelection,QItemSelection)) );
81 connect( m_selectionModel->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(tryDisableEditing()) );
88 #ifndef HAVE_MOUSEPOPUPMENUIMPLEMENTATION
91 QMenu *popup = createStandardContextMenu();
92 connect( popup, SIGNAL(triggered(QAction*)),
93 this, SLOT(menuActivated(QAction*)) );
95 popup->addSeparator();
96 QAction * act = actionCollection->action(QLatin1String(
"copyIntoTitle");
97 popup->addAction(act);
98 act = actionCollection->action(QLatin1String(
"insert_checkmark"));
99 act->setEnabled( !isReadOnly() );
100 popup->addAction(act);
102 if (!KApplication::kApplication()->clipboard()->text().isEmpty())
104 act = actionCollection->action(QLatin1String(
"paste_plain_text"));
105 act->setEnabled( !isReadOnly() );
106 popup->addAction( act );
108 popup->exec( event->globalPos() );
115 QMenu *popup = mousePopupMenu();
117 popup->addSeparator();
118 QAction * act = actionCollection->action(QLatin1String(
"copyIntoTitle"));
119 popup->addAction(act);
120 act = actionCollection->action(QLatin1String(
"insert_checkmark"));
121 act->setEnabled( !isReadOnly() );
122 popup->addAction(act);
124 if (!KApplication::kApplication()->clipboard()->text().isEmpty())
126 act = actionCollection->action(QLatin1String(
"paste_plain_text"));
127 act->setEnabled( !isReadOnly() );
128 popup->addAction( act );
131 aboutToShowContextMenu(popup);
139 actionCollection = collection;
141 connect(actionCollection->action(QLatin1String(
"auto_bullet")), SIGNAL(triggered()), SLOT(
onAutoBullet()));
142 connect(actionCollection->action(QLatin1String(
"auto_decimal")), SIGNAL(triggered()), SLOT(
onAutoDecimal()));
143 connect(actionCollection->action(QLatin1String(
"manage_link")), SIGNAL(triggered()), SLOT(
onLinkify()));
144 connect(actionCollection->action(QLatin1String(
"insert_checkmark")), SIGNAL(triggered()), SLOT(
addCheckmark()));
145 connect(actionCollection->action(QLatin1String(
"manual_save")), SIGNAL(triggered()), SLOT(
savePage()));
146 connect(actionCollection->action(QLatin1String(
"insert_date")), SIGNAL(triggered()), SLOT(
insertDate()));
151 insertPlainText(KGlobal::locale()->formatDateTime(QDateTime::currentDateTime(), KLocale::ShortDate) + QLatin1Char(
' '));
157 Q_UNUSED( deselected )
163 if ( !m_selectionModel->hasSelection() )
164 return setReadOnly(
true);
166 QModelIndexList list = m_selectionModel->selectedRows();
167 if ( list.size() != 1 )
168 return setReadOnly(
true);
170 Item item = list.first().data( EntityTreeModel::ItemRole ).value<Item>();
172 if ( !item.isValid() )
173 return setReadOnly(
true);
176 return setReadOnly(
true);
185 QList<QTreeWidgetItem*> selection = bookshelf->selectedItems();
186 int selectionSize = selection.size();
188 if (selectionSize != 1) {
191 KJotsPage *newPage =
dynamic_cast<KJotsPage*
>(selection[0]);
195 setEnabled(newPage->isEditable());
196 setReadOnly(!newPage->isEditable());
197 if ( currentPage != newPage ) {
199 currentPage->setCursor(textCursor());
201 currentPage = newPage;
203 setDocument(currentPage->body());
204 if ( !currentPage->getCursor().isNull() ) {
205 setTextCursor(currentPage->getCursor());
208 QStackedWidget *stack =
static_cast<QStackedWidget*
>(parent());
209 stack->setCurrentWidget(
this);
212 if ( textCursor().atStart() )
217 moveCursor(QTextCursor::Right);
218 moveCursor(QTextCursor::Left);
229 KTextEdit::AutoFormatting currentFormatting = autoFormatting();
233 if ( currentFormatting == KTextEdit::AutoBulletList ) {
234 setAutoFormatting(KTextEdit::AutoNone);
235 actionCollection->action(QLatin1String(
"auto_bullet"))->setChecked(
false );
237 setAutoFormatting(KTextEdit::AutoBulletList);
238 actionCollection->action(QLatin1String(
"auto_bullet"))->setChecked(
true );
242 void KJotsEdit::createAutoDecimalList(
void )
244 QTextCursor cursor = textCursor();
245 cursor.beginEditBlock();
247 QTextBlockFormat blockFmt = cursor.blockFormat();
249 QTextListFormat listFmt;
250 listFmt.setStyle(QTextListFormat::ListDecimal);
251 listFmt.setIndent(blockFmt.indent() + 1);
253 blockFmt.setIndent(0);
254 cursor.setBlockFormat(blockFmt);
256 cursor.createList(listFmt);
258 cursor.endEditBlock();
259 setTextCursor(cursor);
264 QTextCursor cursor = textCursor();
266 if (cursor.currentList()) {
270 QString blockText = cursor.block().text();
272 if (blockText.length() == 2 && blockText == QLatin1String(
"1."))
274 cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor);
275 cursor.removeSelectedText();
276 createAutoDecimalList();
282 if (allowAutoDecimal ==
true ) {
283 allowAutoDecimal =
false;
284 disconnect(
this, SIGNAL(textChanged()),
this, SLOT(
DecimalList()));
285 actionCollection->action(QLatin1String(
"auto_decimal"))->setChecked(
false );
287 allowAutoDecimal =
true;
288 connect(
this, SIGNAL(textChanged()),
this, SLOT(
DecimalList()));
289 actionCollection->action(QLatin1String(
"auto_decimal"))->setChecked(
true );
297 QPointer<KJotsLinkDialog> linkDialog =
new KJotsLinkDialog( const_cast<QAbstractItemModel *>(m_selectionModel->model()),
this);
298 linkDialog->setLinkText(currentLinkText());
299 linkDialog->setLinkUrl(currentLinkUrl());
301 if (linkDialog->exec()) {
302 updateLink(linkDialog->linkUrl(), linkDialog->linkText());
310 QTextCursor cursor = textCursor();
311 static const QChar unicode[] = {0x2713};
312 int size =
sizeof(unicode) /
sizeof(QChar);
313 cursor.insertText( QString::fromRawData(unicode, size) );
318 if ( source->formats().contains(QLatin1String(
"kjots/internal_link")) ) {
320 }
else if ( source->hasUrls() ) {
323 return KTextEdit::canInsertFromMimeData(source);
329 if ( source->formats().contains(QLatin1String(
"kjots/internal_link")) ) {
330 insertHtml(QLatin1String(source->data(QLatin1String(
"kjots/internal_link"))));
331 }
else if ( source->hasUrls() ) {
332 foreach (
const QUrl &url, source->urls() ) {
333 if ( url.isValid() ) {
334 QString html = QString::fromLatin1(
"<a href='%1'>%2</a> " )
335 .arg(QString::fromUtf8(url.toEncoded()))
336 .arg(url.toString(QUrl::RemovePassword));
340 }
else if( source->hasHtml() ) {
344 QString str = source->html();
346 while ((styleBegin = str.indexOf(QLatin1String(
"style=\""), styleBegin, Qt::CaseInsensitive) + 7) != (-1 + 7)) {
347 int styleEnd = str.indexOf(QLatin1Char(
'"'), styleBegin);
348 int styleFragmentStart = styleBegin;
349 int styleFragmentEnd = styleBegin;
350 while ((styleFragmentEnd = str.indexOf(QLatin1String(
";"), styleFragmentEnd) + 1) != (-1 + 1)) {
351 if (styleFragmentEnd > styleEnd)
break;
352 int fragmentLength = styleFragmentEnd-styleFragmentStart;
353 if (str.mid(styleFragmentStart, fragmentLength).contains(QLatin1String(
"margin"), Qt::CaseInsensitive))
355 str.remove(styleFragmentStart, fragmentLength);
356 styleEnd -= fragmentLength;
357 styleFragmentEnd = styleFragmentStart;
359 if (styleBegin == styleEnd)
361 str.remove(styleBegin-7, 7+1);
364 styleFragmentStart = styleFragmentEnd;
367 styleBegin = styleEnd;
372 KTextEdit::insertFromMimeData(source);
380 if ( ( event->modifiers() & Qt::ControlModifier ) && ( event->button() & Qt::LeftButton )
381 && !anchorAt(event->pos()).isEmpty() )
383 QUrl anchor(anchorAt(event->pos()));
384 if ( anchor.scheme() ==
"kjots" ) {
385 quint64 target = anchor.path().mid(1).toULongLong();
386 bookshelf->jumpToId(target);
388 new KRun ( anchor,
this );
392 KTextEdit::mouseReleaseEvent(event);
397 QString text = KApplication::kApplication()->clipboard()->text();
400 insertPlainText(text);
406 if ( event->type() == QEvent::WindowDeactivate )
410 return KRichTextWidget::event( event );
416 KRichTextWidget::focusOutEvent(event);
421 if ( !document()->isModified() )
424 QModelIndexList rows = m_selectionModel->selectedRows();
426 if (rows.size() != 1)
429 QModelIndex index = rows.at( 0 );
431 Item item = index.data( EntityTreeModel::ItemRole ).value<Item>();
433 if ( !item.isValid() )
436 if (!item.hasPayload<KMime::Message::Ptr>())
439 QAbstractItemModel *model =
const_cast<QAbstractItemModel *
>(m_selectionModel->model());
441 document()->setModified(
false );
442 document()->setProperty(
"textCursor", QVariant::fromValue( textCursor() ) );
448 #include "kjotsedit.moc"
virtual void focusOutEvent(QFocusEvent *)
virtual bool event(QEvent *event)
virtual bool canInsertFromMimeData(const QMimeData *) const
virtual void mouseReleaseEvent(QMouseEvent *)
Override to make ctrl+click follow links.
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
void onBookshelfSelection(void)
void pastePlainText(void)
void delayedInitialization(KActionCollection *)
virtual void insertFromMimeData(const QMimeData *)
void mousePopupMenuImplementation(const QPoint &pos)
virtual void contextMenuEvent(QContextMenuEvent *)