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

kjots

  • sources
  • kde-4.12
  • 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 <QContextMenuEvent>
34 #include <QClipboard>
35 #include <QItemSelectionModel>
36 #include <QPointer>
37 
38 #include <kaction.h>
39 #include <kactioncollection.h>
40 #include <krun.h>
41 #include <KApplication>
42 #include <KLocale>
43 
44 #include "kjotslinkdialog.h"
45 
46 #include <akonadi/entitytreemodel.h>
47 #include <akonadi/item.h>
48 
49 #include <KMime/Message>
50 
51 #include <kdebug.h>
52 #include "kjotsmodel.h"
53 #include "kjotslockattribute.h"
54 
55 
56 #ifndef KDE_USE_FINAL
57 Q_DECLARE_METATYPE(QTextDocument*)
58 #endif
59 Q_DECLARE_METATYPE(QTextCursor)
60 
61 using namespace Akonadi;
62 
63 KJotsEdit::KJotsEdit ( QItemSelectionModel *selectionModel, QWidget *parent )
64  : KRichTextWidget(parent),
65  actionCollection( 0 ),
66  allowAutoDecimal(false),
67  m_selectionModel( selectionModel )
68 {
69  setAcceptRichText(true);
70  setWordWrapMode(QTextOption::WordWrap);
71  setCheckSpellingEnabled(true);
72  setRichTextSupport( FullTextFormattingSupport
73  | FullListSupport
74  | SupportAlignment
75  | SupportRuleLine
76  | SupportFormatPainting );
77 
78  setFocusPolicy(Qt::StrongFocus);
79 
80  connect( m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(selectionChanged(QItemSelection,QItemSelection)) );
81  connect( m_selectionModel->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(tryDisableEditing()) );
82 }
83 
84 KJotsEdit::~KJotsEdit()
85 {
86 }
87 
88 #ifndef HAVE_MOUSEPOPUPMENUIMPLEMENTATION
89 void KJotsEdit::contextMenuEvent( QContextMenuEvent *event )
90 {
91  QMenu *popup = createStandardContextMenu();
92  connect( popup, SIGNAL(triggered(QAction*)),
93  this, SLOT(menuActivated(QAction*)) );
94 
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);
101 
102  if (!KApplication::kApplication()->clipboard()->text().isEmpty())
103  {
104  act = actionCollection->action(QLatin1String("paste_plain_text"));
105  act->setEnabled( !isReadOnly() );
106  popup->addAction( act );
107  }
108  popup->exec( event->globalPos() );
109  delete popup;
110 }
111 #endif
112 
113 void KJotsEdit::mousePopupMenuImplementation(const QPoint& pos)
114 {
115  QMenu *popup = mousePopupMenu();
116  if ( popup ) {
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);
123 
124  if (!KApplication::kApplication()->clipboard()->text().isEmpty())
125  {
126  act = actionCollection->action(QLatin1String("paste_plain_text"));
127  act->setEnabled( !isReadOnly() );
128  popup->addAction( act );
129  }
130 
131  aboutToShowContextMenu(popup);
132  popup->exec( pos );
133  delete popup;
134  }
135 }
136 
137 void KJotsEdit::delayedInitialization ( KActionCollection *collection )
138 {
139  actionCollection = collection;
140 
141  connect(actionCollection->action(QLatin1String("auto_bullet")), SIGNAL(triggered()), SLOT(onAutoBullet()));
142  connect(actionCollection->action(QLatin1String("auto_decimal")), SIGNAL(triggered()), SLOT(onAutoDecimal())); //auto decimal list
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()));
147 }
148 
149 void KJotsEdit::insertDate()
150 {
151  insertPlainText(KGlobal::locale()->formatDateTime(QDateTime::currentDateTime(), KLocale::ShortDate) + QLatin1Char(' '));
152 }
153 
154 void KJotsEdit::selectionChanged( const QItemSelection& selected, const QItemSelection& deselected )
155 {
156  Q_UNUSED( selected )
157  Q_UNUSED( deselected )
158  tryDisableEditing();
159 }
160 
161 void KJotsEdit::tryDisableEditing()
162 {
163  if ( !m_selectionModel->hasSelection() )
164  return setReadOnly(true);
165 
166  QModelIndexList list = m_selectionModel->selectedRows();
167  if ( list.size() != 1 )
168  return setReadOnly(true);
169 
170  Item item = list.first().data( EntityTreeModel::ItemRole ).value<Item>();
171 
172  if ( !item.isValid() )
173  return setReadOnly(true);
174 
175  if ( item.hasAttribute<KJotsLockAttribute>() )
176  return setReadOnly(true);
177 
178  setReadOnly(false);
179 }
180 
181 void KJotsEdit::onBookshelfSelection ( void )
182 {
183  // TODO: PORT. Review and remove. Possibly keep the bug workaround.
184 #if 0
185  QList<QTreeWidgetItem*> selection = bookshelf->selectedItems();
186  int selectionSize = selection.size();
187 
188  if (selectionSize != 1) {
189  disableEditing();
190  } else {
191  KJotsPage *newPage = dynamic_cast<KJotsPage*>(selection[0]);
192  if ( !newPage ) {
193  disableEditing();
194  } else {
195  setEnabled(newPage->isEditable());
196  setReadOnly(!newPage->isEditable());
197  if ( currentPage != newPage ) {
198  if ( currentPage ) {
199  currentPage->setCursor(textCursor());
200  }
201  currentPage = newPage;
202 
203  setDocument(currentPage->body());
204  if ( !currentPage->getCursor().isNull() ) {
205  setTextCursor(currentPage->getCursor());
206  }
207 
208  QStackedWidget *stack = static_cast<QStackedWidget*>(parent());
209  stack->setCurrentWidget(this);
210  setFocus();
211 
212  if ( textCursor().atStart() )
213  {
214  // Reflect formatting when switching pages and the first word is formatted
215  // Work-around for qrextedit bug. The format does not seem to exist
216  // before the first character. Submitted to qt-bugs, id 192886.
217  moveCursor(QTextCursor::Right);
218  moveCursor(QTextCursor::Left);
219  }
220 
221  }
222  }
223  }
224 #endif
225 }
226 
227 void KJotsEdit::onAutoBullet ( void )
228 {
229  KTextEdit::AutoFormatting currentFormatting = autoFormatting();
230 
231  //TODO: set line spacing properly.
232 
233  if ( currentFormatting == KTextEdit::AutoBulletList ) {
234  setAutoFormatting(KTextEdit::AutoNone);
235  actionCollection->action(QLatin1String("auto_bullet"))->setChecked( false );
236  } else {
237  setAutoFormatting(KTextEdit::AutoBulletList);
238  actionCollection->action(QLatin1String("auto_bullet"))->setChecked( true );
239  }
240 }
241 
242 void KJotsEdit::createAutoDecimalList( void )
243 {//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.
244  QTextCursor cursor = textCursor();
245  cursor.beginEditBlock();
246 
247  QTextBlockFormat blockFmt = cursor.blockFormat();
248 
249  QTextListFormat listFmt;
250  listFmt.setStyle(QTextListFormat::ListDecimal);
251  listFmt.setIndent(blockFmt.indent() + 1);
252 
253  blockFmt.setIndent(0);
254  cursor.setBlockFormat(blockFmt);
255 
256  cursor.createList(listFmt);
257 
258  cursor.endEditBlock();
259  setTextCursor(cursor);
260 }
261 
262 void KJotsEdit::DecimalList( void )
263 {
264  QTextCursor cursor = textCursor();
265 
266  if (cursor.currentList()) {
267  return;
268  }
269 
270  QString blockText = cursor.block().text();
271 
272  if (blockText.length() == 2 && blockText == QLatin1String("1."))
273  {
274  cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor);
275  cursor.removeSelectedText();
276  createAutoDecimalList();
277  }
278 }
279 
280 void KJotsEdit::onAutoDecimal( void )
281 {
282  if (allowAutoDecimal == true ) {
283  allowAutoDecimal = false;
284  disconnect(this, SIGNAL(textChanged()), this, SLOT(DecimalList()));
285  actionCollection->action(QLatin1String("auto_decimal"))->setChecked( false );
286  } else {
287  allowAutoDecimal = true;
288  connect(this, SIGNAL(textChanged()), this, SLOT(DecimalList()));
289  actionCollection->action(QLatin1String("auto_decimal"))->setChecked( true );
290  }
291 }
292 
293 
294 void KJotsEdit::onLinkify ( void )
295 {
296  selectLinkText();
297  QPointer<KJotsLinkDialog> linkDialog = new KJotsLinkDialog( const_cast<QAbstractItemModel *>(m_selectionModel->model()), this);
298  linkDialog->setLinkText(currentLinkText());
299  linkDialog->setLinkUrl(currentLinkUrl());
300 
301  if (linkDialog->exec()) {
302  updateLink(linkDialog->linkUrl(), linkDialog->linkText());
303  }
304 
305  delete linkDialog;
306 }
307 
308 void KJotsEdit::addCheckmark( void )
309 {
310  QTextCursor cursor = textCursor();
311  static const QChar unicode[] = {0x2713};
312  int size = sizeof(unicode) / sizeof(QChar);
313  cursor.insertText( QString::fromRawData(unicode, size) );
314 }
315 
316 bool KJotsEdit::canInsertFromMimeData ( const QMimeData *source ) const
317 {
318  if ( source->formats().contains(QLatin1String("kjots/internal_link")) ) {
319  return true;
320  } else if ( source->hasUrls() ) {
321  return true;
322  } else {
323  return KTextEdit::canInsertFromMimeData(source);
324  }
325 }
326 
327 void KJotsEdit::insertFromMimeData ( const QMimeData *source )
328 {
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));
337  insertHtml(html);
338  }
339  }
340  } else if( source->hasHtml() ) {
341  // Don't have an action to set top and bottom margins on paragraphs yet.
342  // Remove the margins for all inserted html.
343 // kDebug() << source->html();
344  QString str = source->html();
345  int styleBegin = 0;
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))
354  {
355  str.remove(styleFragmentStart, fragmentLength);
356  styleEnd -= fragmentLength;
357  styleFragmentEnd = styleFragmentStart;
358 
359  if (styleBegin == styleEnd)
360  {
361  str.remove(styleBegin-7, 7+1); // remove the now empty style attribute.
362  }
363  } else {
364  styleFragmentStart = styleFragmentEnd;
365  }
366  }
367  styleBegin = styleEnd;
368  }
369 // kDebug() << str;
370  insertHtml(str);
371  } else {
372  KTextEdit::insertFromMimeData(source);
373  }
374 }
375 
376 void KJotsEdit::mouseReleaseEvent(QMouseEvent *event)
377 {
378  // TODO: PORT
379 #if 0
380  if ( ( event->modifiers() & Qt::ControlModifier ) && ( event->button() & Qt::LeftButton )
381  && !anchorAt(event->pos()).isEmpty() )
382  {
383  QUrl anchor(anchorAt(event->pos()));
384  if ( anchor.scheme() == "kjots" ) {
385  quint64 target = anchor.path().mid(1).toULongLong();
386  bookshelf->jumpToId(target);
387  } else {
388  new KRun ( anchor, this );
389  }
390  }
391 #endif
392  KTextEdit::mouseReleaseEvent(event);
393 }
394 
395 void KJotsEdit::pastePlainText()
396 {
397  QString text = KApplication::kApplication()->clipboard()->text();
398  if (!text.isEmpty())
399  {
400  insertPlainText(text);
401  }
402 }
403 
404 bool KJotsEdit::event( QEvent *event )
405 {
406  if ( event->type() == QEvent::WindowDeactivate )
407  {
408  savePage();
409  }
410  return KRichTextWidget::event( event );
411 }
412 
413 void KJotsEdit::focusOutEvent( QFocusEvent* event )
414 {
415  savePage();
416  KRichTextWidget::focusOutEvent(event);
417 }
418 
419 void KJotsEdit::savePage()
420 {
421  if ( !document()->isModified() )
422  return;
423 
424  QModelIndexList rows = m_selectionModel->selectedRows();
425 
426  if (rows.size() != 1)
427  return;
428 
429  QModelIndex index = rows.at( 0 );
430 
431  Item item = index.data( EntityTreeModel::ItemRole ).value<Item>();
432 
433  if ( !item.isValid() )
434  return;
435 
436  if (!item.hasPayload<KMime::Message::Ptr>())
437  return;
438 
439  QAbstractItemModel *model = const_cast<QAbstractItemModel *>(m_selectionModel->model());
440 
441  document()->setModified( false );
442  document()->setProperty( "textCursor", QVariant::fromValue( textCursor() ) );
443  model->setData( index, QVariant::fromValue( document() ), KJotsModel::DocumentRole );
444 }
445 
446 
447 
448 #include "kjotsedit.moc"
449 /* ex: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab: */
450 /* 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:413
KJotsEdit::event
virtual bool event(QEvent *event)
Definition: kjotsedit.cpp:404
KJotsEdit::onLinkify
void onLinkify(void)
Definition: kjotsedit.cpp:294
KJotsEdit::onAutoBullet
void onAutoBullet(void)
Definition: kjotsedit.cpp:227
QWidget
KJotsEdit::canInsertFromMimeData
virtual bool canInsertFromMimeData(const QMimeData *) const
Definition: kjotsedit.cpp:316
kjotslinkdialog.h
KJotsEdit::mouseReleaseEvent
virtual void mouseReleaseEvent(QMouseEvent *)
Override to make ctrl+click follow links.
Definition: kjotsedit.cpp:376
KJotsEdit::selectionChanged
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
Definition: kjotsedit.cpp:154
KJotsEdit
Definition: kjotsedit.h:35
KJotsLinkDialog
Definition: kjotslinkdialog.h:35
KJotsEdit::onBookshelfSelection
void onBookshelfSelection(void)
Definition: kjotsedit.cpp:181
KRichTextWidget
KJotsEdit::tryDisableEditing
void tryDisableEditing()
Definition: kjotsedit.cpp:161
KJotsEdit::onAutoDecimal
void onAutoDecimal(void)
Definition: kjotsedit.cpp:280
KJotsEdit::pastePlainText
void pastePlainText(void)
Definition: kjotsedit.cpp:395
kjotsedit.h
KJotsEdit::delayedInitialization
void delayedInitialization(KActionCollection *)
Definition: kjotsedit.cpp:137
KJotsLockAttribute
Definition: kjotslockattribute.h:27
KJotsModel::DocumentRole
Definition: kjotsmodel.h:84
KJotsEdit::savePage
void savePage()
Definition: kjotsedit.cpp:419
KJotsEdit::insertDate
void insertDate()
Definition: kjotsedit.cpp:149
kjotslockattribute.h
kjotsmodel.h
KJotsEdit::insertFromMimeData
virtual void insertFromMimeData(const QMimeData *)
Definition: kjotsedit.cpp:327
KJotsEdit::mousePopupMenuImplementation
void mousePopupMenuImplementation(const QPoint &pos)
Definition: kjotsedit.cpp:113
KJotsEdit::DecimalList
void DecimalList(void)
Definition: kjotsedit.cpp:262
KJotsEdit::contextMenuEvent
virtual void contextMenuEvent(QContextMenuEvent *)
Definition: kjotsedit.cpp:89
KJotsEdit::addCheckmark
void addCheckmark(void)
Definition: kjotsedit.cpp:308
KJotsEdit::~KJotsEdit
virtual ~KJotsEdit()
Definition: kjotsedit.cpp:84
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:55:39 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

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