• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kjots

  • sources
  • kde-4.14
  • kdepim
  • kjots
kjotsedit.cpp
Go to the documentation of this file.
1 //
2 // kjots
3 //
4 // Copyright (C) 1997 Christoph Neerfeld <Christoph.Neerfeld@home.ivm.de>
5 // Copyright (C) 2002, 2003 Aaron J. Seigo <aseigo@kde.org>
6 // Copyright (C) 2003 Stanislav Kljuhhin <crz@hot.ee>
7 // Copyright (C) 2005-2006 Jaison Lee <lee.jaison@gmail.com>
8 // Copyright (C) 2007-2008 Stephen Kelly <steveire@gmail.com>
9 //
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
14 //
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 //
24 
25 //Own Header
26 #include "kjotsedit.h"
27 
28 #include <QMimeData>
29 #include <QTextCursor>
30 #include <QStackedWidget>
31 #include <QUrl>
32 #include <QMenu>
33 #include <QItemSelectionModel>
34 #include <QPointer>
35 #include <QClipboard>
36 
37 #include <kaction.h>
38 #include <kactioncollection.h>
39 #include <krun.h>
40 #include <KApplication>
41 
42 #include "kjotslinkdialog.h"
43 
44 #include <akonadi/entitytreemodel.h>
45 #include <akonadi/item.h>
46 
47 #include <KMime/Message>
48 
49 #include <kdebug.h>
50 #include "kjotsmodel.h"
51 #include "noteshared/attributes/notelockattribute.h"
52 #include "noteshared/editor/noteeditorutils.h"
53 
54 #ifndef KDE_USE_FINAL
55 Q_DECLARE_METATYPE(QTextDocument*)
56 #endif
57 Q_DECLARE_METATYPE(QTextCursor)
58 
59 using namespace Akonadi;
60 
61 KJotsEdit::KJotsEdit ( QItemSelectionModel *selectionModel, QWidget *parent )
62  : KRichTextWidget(parent),
63  actionCollection( 0 ),
64  allowAutoDecimal(false),
65  m_selectionModel( selectionModel )
66 {
67  setAcceptRichText(true);
68  setWordWrapMode(QTextOption::WordWrap);
69  setCheckSpellingEnabled(true);
70  setRichTextSupport( FullTextFormattingSupport
71  | FullListSupport
72  | SupportAlignment
73  | SupportRuleLine
74  | SupportFormatPainting );
75 
76  setFocusPolicy(Qt::StrongFocus);
77 
78  connect( m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(selectionChanged(QItemSelection,QItemSelection)) );
79  connect( m_selectionModel->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(tryDisableEditing()) );
80 }
81 
82 KJotsEdit::~KJotsEdit()
83 {
84 }
85 
86 void KJotsEdit::mousePopupMenuImplementation(const QPoint& pos)
87 {
88  QMenu *popup = mousePopupMenu();
89  if ( popup ) {
90  popup->addSeparator();
91  QAction * act = actionCollection->action(QLatin1String("copyIntoTitle"));
92  popup->addAction(act);
93  act = actionCollection->action(QLatin1String("insert_checkmark"));
94  act->setEnabled( !isReadOnly() );
95  popup->addAction(act);
96 
97  if (!KApplication::kApplication()->clipboard()->text().isEmpty())
98  {
99  act = actionCollection->action(QLatin1String("paste_plain_text"));
100  act->setEnabled( !isReadOnly() );
101  popup->addAction( act );
102  }
103 
104  aboutToShowContextMenu(popup);
105  popup->exec( pos );
106  delete popup;
107  }
108 }
109 
110 void KJotsEdit::delayedInitialization ( KActionCollection *collection )
111 {
112  actionCollection = collection;
113 
114  connect(actionCollection->action(QLatin1String("auto_bullet")), SIGNAL(triggered()), SLOT(onAutoBullet()));
115  connect(actionCollection->action(QLatin1String("auto_decimal")), SIGNAL(triggered()), SLOT(onAutoDecimal())); //auto decimal list
116  connect(actionCollection->action(QLatin1String("manage_link")), SIGNAL(triggered()), SLOT(onLinkify()));
117  connect(actionCollection->action(QLatin1String("insert_checkmark")), SIGNAL(triggered()), SLOT(addCheckmark()));
118  connect(actionCollection->action(QLatin1String("manual_save")), SIGNAL(triggered()), SLOT(savePage()));
119  connect(actionCollection->action(QLatin1String("insert_date")), SIGNAL(triggered()), SLOT(insertDate()));
120 }
121 
122 void KJotsEdit::insertDate()
123 {
124  NoteShared::NoteEditorUtils noteEditorUtils;
125  noteEditorUtils.insertDate(this);
126 }
127 
128 void KJotsEdit::selectionChanged( const QItemSelection& selected, const QItemSelection& deselected )
129 {
130  Q_UNUSED( selected )
131  Q_UNUSED( deselected )
132  tryDisableEditing();
133 }
134 
135 void KJotsEdit::tryDisableEditing()
136 {
137  if ( !m_selectionModel->hasSelection() )
138  return setReadOnly(true);
139 
140  QModelIndexList list = m_selectionModel->selectedRows();
141  if ( list.size() != 1 )
142  return setReadOnly(true);
143 
144  Item item = list.first().data( EntityTreeModel::ItemRole ).value<Item>();
145 
146  if ( !item.isValid() )
147  return setReadOnly(true);
148 
149  if ( item.hasAttribute<NoteShared::NoteLockAttribute>() )
150  return setReadOnly(true);
151 
152  setReadOnly(false);
153 }
154 
155 void KJotsEdit::onBookshelfSelection ( void )
156 {
157  // TODO: PORT. Review and remove. Possibly keep the bug workaround.
158 #if 0
159  QList<QTreeWidgetItem*> selection = bookshelf->selectedItems();
160  int selectionSize = selection.size();
161 
162  if (selectionSize != 1) {
163  disableEditing();
164  } else {
165  KJotsPage *newPage = dynamic_cast<KJotsPage*>(selection[0]);
166  if ( !newPage ) {
167  disableEditing();
168  } else {
169  setEnabled(newPage->isEditable());
170  setReadOnly(!newPage->isEditable());
171  if ( currentPage != newPage ) {
172  if ( currentPage ) {
173  currentPage->setCursor(textCursor());
174  }
175  currentPage = newPage;
176 
177  setDocument(currentPage->body());
178  if ( !currentPage->getCursor().isNull() ) {
179  setTextCursor(currentPage->getCursor());
180  }
181 
182  QStackedWidget *stack = static_cast<QStackedWidget*>(parent());
183  stack->setCurrentWidget(this);
184  setFocus();
185 
186  if ( textCursor().atStart() )
187  {
188  // Reflect formatting when switching pages and the first word is formatted
189  // Work-around for qrextedit bug. The format does not seem to exist
190  // before the first character. Submitted to qt-bugs, id 192886.
191  moveCursor(QTextCursor::Right);
192  moveCursor(QTextCursor::Left);
193  }
194 
195  }
196  }
197  }
198 #endif
199 }
200 
201 void KJotsEdit::onAutoBullet ( void )
202 {
203  KTextEdit::AutoFormatting currentFormatting = autoFormatting();
204 
205  //TODO: set line spacing properly.
206 
207  if ( currentFormatting == KTextEdit::AutoBulletList ) {
208  setAutoFormatting(KTextEdit::AutoNone);
209  actionCollection->action(QLatin1String("auto_bullet"))->setChecked( false );
210  } else {
211  setAutoFormatting(KTextEdit::AutoBulletList);
212  actionCollection->action(QLatin1String("auto_bullet"))->setChecked( true );
213  }
214 }
215 
216 void KJotsEdit::createAutoDecimalList( void )
217 {//this is an adaptation of Qt's createAutoBulletList() function for creating a bulleted list, except in this case I use it to create a decimal list.
218  QTextCursor cursor = textCursor();
219  cursor.beginEditBlock();
220 
221  QTextBlockFormat blockFmt = cursor.blockFormat();
222 
223  QTextListFormat listFmt;
224  listFmt.setStyle(QTextListFormat::ListDecimal);
225  listFmt.setIndent(blockFmt.indent() + 1);
226 
227  blockFmt.setIndent(0);
228  cursor.setBlockFormat(blockFmt);
229 
230  cursor.createList(listFmt);
231 
232  cursor.endEditBlock();
233  setTextCursor(cursor);
234 }
235 
236 void KJotsEdit::DecimalList( void )
237 {
238  QTextCursor cursor = textCursor();
239 
240  if (cursor.currentList()) {
241  return;
242  }
243 
244  QString blockText = cursor.block().text();
245 
246  if (blockText.length() == 2 && blockText == QLatin1String("1."))
247  {
248  cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor);
249  cursor.removeSelectedText();
250  createAutoDecimalList();
251  }
252 }
253 
254 void KJotsEdit::onAutoDecimal( void )
255 {
256  if (allowAutoDecimal == true ) {
257  allowAutoDecimal = false;
258  disconnect(this, SIGNAL(textChanged()), this, SLOT(DecimalList()));
259  actionCollection->action(QLatin1String("auto_decimal"))->setChecked( false );
260  } else {
261  allowAutoDecimal = true;
262  connect(this, SIGNAL(textChanged()), this, SLOT(DecimalList()));
263  actionCollection->action(QLatin1String("auto_decimal"))->setChecked( true );
264  }
265 }
266 
267 
268 void KJotsEdit::onLinkify ( void )
269 {
270  selectLinkText();
271  QPointer<KJotsLinkDialog> linkDialog = new KJotsLinkDialog( const_cast<QAbstractItemModel *>(m_selectionModel->model()), this);
272  linkDialog->setLinkText(currentLinkText());
273  linkDialog->setLinkUrl(currentLinkUrl());
274 
275  if (linkDialog->exec()) {
276  updateLink(linkDialog->linkUrl(), linkDialog->linkText());
277  }
278 
279  delete linkDialog;
280 }
281 
282 void KJotsEdit::addCheckmark( void )
283 {
284  QTextCursor cursor = textCursor();
285  NoteShared::NoteEditorUtils noteEditorUtils;
286  noteEditorUtils.addCheckmark(cursor);
287 }
288 
289 bool KJotsEdit::canInsertFromMimeData ( const QMimeData *source ) const
290 {
291  if ( source->formats().contains(QLatin1String("kjots/internal_link")) ) {
292  return true;
293  } else if ( source->hasUrls() ) {
294  return true;
295  } else {
296  return KTextEdit::canInsertFromMimeData(source);
297  }
298 }
299 
300 void KJotsEdit::insertFromMimeData ( const QMimeData *source )
301 {
302  if ( source->formats().contains(QLatin1String("kjots/internal_link")) ) {
303  insertHtml(QLatin1String(source->data(QLatin1String("kjots/internal_link"))));
304  } else if ( source->hasUrls() ) {
305  foreach ( const QUrl &url, source->urls() ) {
306  if ( url.isValid() ) {
307  QString html = QString::fromLatin1( "<a href='%1'>%2</a> " )
308  .arg(QString::fromUtf8(url.toEncoded()))
309  .arg(url.toString(QUrl::RemovePassword));
310  insertHtml(html);
311  }
312  }
313  } else if( source->hasHtml() ) {
314  // Don't have an action to set top and bottom margins on paragraphs yet.
315  // Remove the margins for all inserted html.
316 // kDebug() << source->html();
317  QString str = source->html();
318  int styleBegin = 0;
319  while ((styleBegin = str.indexOf(QLatin1String("style=\""), styleBegin, Qt::CaseInsensitive) + 7) != (-1 + 7)) {
320  int styleEnd = str.indexOf(QLatin1Char('"'), styleBegin);
321  int styleFragmentStart = styleBegin;
322  int styleFragmentEnd = styleBegin;
323  while ((styleFragmentEnd = str.indexOf(QLatin1String(";"), styleFragmentEnd) + 1) != (-1 + 1)) {
324  if (styleFragmentEnd > styleEnd) break;
325  int fragmentLength = styleFragmentEnd-styleFragmentStart;
326  if (str.mid(styleFragmentStart, fragmentLength).contains(QLatin1String("margin"), Qt::CaseInsensitive))
327  {
328  str.remove(styleFragmentStart, fragmentLength);
329  styleEnd -= fragmentLength;
330  styleFragmentEnd = styleFragmentStart;
331 
332  if (styleBegin == styleEnd)
333  {
334  str.remove(styleBegin-7, 7+1); // remove the now empty style attribute.
335  }
336  } else {
337  styleFragmentStart = styleFragmentEnd;
338  }
339  }
340  styleBegin = styleEnd;
341  }
342 // kDebug() << str;
343  insertHtml(str);
344  } else {
345  KTextEdit::insertFromMimeData(source);
346  }
347 }
348 
349 void KJotsEdit::mouseReleaseEvent(QMouseEvent *event)
350 {
351  // TODO: PORT
352 #if 0
353  if ( ( event->modifiers() & Qt::ControlModifier ) && ( event->button() & Qt::LeftButton )
354  && !anchorAt(event->pos()).isEmpty() )
355  {
356  QUrl anchor(anchorAt(event->pos()));
357  if ( anchor.scheme() == "kjots" ) {
358  quint64 target = anchor.path().mid(1).toULongLong();
359  bookshelf->jumpToId(target);
360  } else {
361  new KRun ( anchor, this );
362  }
363  }
364 #endif
365  KTextEdit::mouseReleaseEvent(event);
366 }
367 
368 void KJotsEdit::pastePlainText()
369 {
370  QString text = KApplication::kApplication()->clipboard()->text();
371  if (!text.isEmpty())
372  {
373  insertPlainText(text);
374  }
375 }
376 
377 bool KJotsEdit::event( QEvent *event )
378 {
379  if ( event->type() == QEvent::WindowDeactivate )
380  {
381  savePage();
382  }
383  return KRichTextWidget::event( event );
384 }
385 
386 void KJotsEdit::focusOutEvent( QFocusEvent* event )
387 {
388  savePage();
389  KRichTextWidget::focusOutEvent(event);
390 }
391 
392 void KJotsEdit::savePage()
393 {
394  if ( !document()->isModified() )
395  return;
396 
397  QModelIndexList rows = m_selectionModel->selectedRows();
398 
399  if (rows.size() != 1)
400  return;
401 
402  QModelIndex index = rows.at( 0 );
403 
404  Item item = index.data( EntityTreeModel::ItemRole ).value<Item>();
405 
406  if ( !item.isValid() )
407  return;
408 
409  if (!item.hasPayload<KMime::Message::Ptr>())
410  return;
411 
412  QAbstractItemModel *model = const_cast<QAbstractItemModel *>(m_selectionModel->model());
413 
414  document()->setModified( false );
415  document()->setProperty( "textCursor", QVariant::fromValue( textCursor() ) );
416  model->setData( index, QVariant::fromValue( document() ), KJotsModel::DocumentRole );
417 }
418 
419 
420 
421 /* ex: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab: */
422 /* kate: tab-indents off; replace-tabs on; tab-width 4; remove-trailing-space on; encoding utf-8;*/
KJotsEdit::focusOutEvent
virtual void focusOutEvent(QFocusEvent *)
Definition: kjotsedit.cpp:386
QModelIndex
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QEvent
QWidget
QTextCursor::removeSelectedText
void removeSelectedText()
QEvent::type
Type type() const
KJotsEdit::event
virtual bool event(QEvent *event)
Definition: kjotsedit.cpp:377
QMimeData::data
QByteArray data(const QString &mimeType) const
QTextCursor
KJotsEdit::onLinkify
void onLinkify(void)
Definition: kjotsedit.cpp:268
KJotsEdit::onAutoBullet
void onAutoBullet(void)
Definition: kjotsedit.cpp:201
QTextListFormat::setStyle
void setStyle(Style style)
QTextCursor::createList
QTextList * createList(const QTextListFormat &format)
QTextBlockFormat
QMenu::addAction
void addAction(QAction *action)
QPointer
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QTextCursor::currentList
QTextList * currentList() const
KJotsEdit::canInsertFromMimeData
virtual bool canInsertFromMimeData(const QMimeData *) const
Definition: kjotsedit.cpp:289
QVariant::value
T value() const
QPoint
QMouseEvent
QString::remove
QString & remove(int position, int n)
kjotslinkdialog.h
QUrl::toString
QString toString(QFlags< QUrl::FormattingOption > options) const
KJotsEdit::mouseReleaseEvent
virtual void mouseReleaseEvent(QMouseEvent *)
Override to make ctrl+click follow links.
Definition: kjotsedit.cpp:349
KJotsEdit::selectionChanged
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
Definition: kjotsedit.cpp:128
KJotsEdit
Definition: kjotsedit.h:35
QMimeData
QTextCursor::movePosition
bool movePosition(MoveOperation operation, MoveMode mode, int n)
QList::size
int size() const
QTextListFormat::setIndent
void setIndent(int indentation)
KJotsLinkDialog
Definition: kjotslinkdialog.h:35
QTextBlockFormat::setIndent
void setIndent(int indentation)
QString::fromUtf8
QString fromUtf8(const char *str, int size)
QMimeData::hasHtml
bool hasHtml() const
QStackedWidget::setCurrentWidget
void setCurrentWidget(QWidget *widget)
KJotsEdit::onBookshelfSelection
void onBookshelfSelection(void)
Definition: kjotsedit.cpp:155
KRichTextWidget
QMouseEvent::button
Qt::MouseButton button() const
QTextCursor::endEditBlock
void endEditBlock()
QTextListFormat
QString::isEmpty
bool isEmpty() const
QItemSelectionModel::selectedRows
QModelIndexList selectedRows(int column) const
QTextCursor::setBlockFormat
void setBlockFormat(const QTextBlockFormat &format)
QItemSelectionModel::hasSelection
bool hasSelection() const
QUrl::path
QString path() const
KJotsEdit::tryDisableEditing
void tryDisableEditing()
Definition: kjotsedit.cpp:135
QStackedWidget
QMenu::addSeparator
QAction * addSeparator()
QString
QTextBlockFormat::indent
int indent() const
QList
QString::toULongLong
qulonglong toULongLong(bool *ok, int base) const
KJotsEdit::onAutoDecimal
void onAutoDecimal(void)
Definition: kjotsedit.cpp:254
QMenu::exec
QAction * exec()
QUrl::scheme
QString scheme() const
QInputEvent::modifiers
Qt::KeyboardModifiers modifiers() const
KJotsEdit::pastePlainText
void pastePlainText(void)
Definition: kjotsedit.cpp:368
QTextCursor::block
QTextBlock block() const
QMenu
kjotsedit.h
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QUrl
QLatin1Char
QTextCursor::beginEditBlock
void beginEditBlock()
QVariant::fromValue
QVariant fromValue(const T &value)
QTextBlock::text
QString text() const
KJotsEdit::delayedInitialization
void delayedInitialization(KActionCollection *)
Definition: kjotsedit.cpp:110
QItemSelection
KJotsModel::DocumentRole
Definition: kjotsmodel.h:84
KJotsEdit::savePage
void savePage()
Definition: kjotsedit.cpp:392
KJotsEdit::insertDate
void insertDate()
Definition: kjotsedit.cpp:122
QUrl::isValid
bool isValid() const
QString::mid
QString mid(int position, int n) const
QMimeData::hasUrls
bool hasUrls() const
QModelIndex::data
QVariant data(int role) const
QLatin1String
QMimeData::urls
QList< QUrl > urls() const
QTextDocument
QAction
QString::length
int length() const
QAbstractItemModel
QAbstractItemModel::setData
virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
kjotsmodel.h
QString::fromLatin1
QString fromLatin1(const char *str, int size)
QMimeData::formats
virtual QStringList formats() const
KJotsEdit::insertFromMimeData
virtual void insertFromMimeData(const QMimeData *)
Definition: kjotsedit.cpp:300
KJotsEdit::mousePopupMenuImplementation
void mousePopupMenuImplementation(const QPoint &pos)
Definition: kjotsedit.cpp:86
QObject::setProperty
bool setProperty(const char *name, const QVariant &value)
KJotsEdit::DecimalList
void DecimalList(void)
Definition: kjotsedit.cpp:236
QMouseEvent::pos
const QPoint & pos() const
QItemSelectionModel
KJotsEdit::addCheckmark
void addCheckmark(void)
Definition: kjotsedit.cpp:282
KJotsEdit::~KJotsEdit
virtual ~KJotsEdit()
Definition: kjotsedit.cpp:82
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QMimeData::html
QString html() const
QFocusEvent
QItemSelectionModel::model
const QAbstractItemModel * model() const
QTextCursor::blockFormat
QTextBlockFormat blockFormat() const
QAction::setEnabled
void setEnabled(bool)
QUrl::toEncoded
QByteArray toEncoded(QFlags< QUrl::FormattingOption > options) const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:32:12 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kjots

Skip menu "kjots"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal