• 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
kjotswidget.cpp
Go to the documentation of this file.
1 /*
2  This file is part of 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-2009 Stephen Kelly <steveire@gmail.com>
9 
10  This library is free software; you can redistribute it and/or modify it
11  under the terms of the GNU Library General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or (at your
13  option) any later version.
14 
15  This library is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
18  License for more details.
19 
20  You should have received a copy of the GNU Library General Public License
21  along with this library; see the file COPYING.LIB. If not, write to the
22  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23  02110-1301, USA.
24 */
25 
26 #include "kjotswidget.h"
27 
28 // Qt
29 #include <QHBoxLayout>
30 #include <QInputDialog>
31 #include <QSplitter>
32 #include <QStackedWidget>
33 #include <QTextCursor>
34 #include <QTextDocument>
35 #include <QTextDocumentFragment>
36 #include <QTimer>
37 #include <QPrintDialog>
38 #include <QPainter>
39 #include <QPointer>
40 #include <QPrinter>
41 #include <QAbstractTextDocumentLayout>
42 #include <QDBusConnection>
43 
44 // Akonadi
45 #include <akonadi/control.h>
46 #include <akonadi/collectiondeletejob.h>
47 #include <akonadi/collectioncreatejob.h>
48 #include <akonadi/changerecorder.h>
49 #include <akonadi/entitydisplayattribute.h>
50 #include <akonadi/entitytreeview.h>
51 #include <akonadi/etmviewstatesaver.h>
52 #include <akonadi/item.h>
53 #include <Akonadi/ItemCreateJob>
54 #include <Akonadi/ItemDeleteJob>
55 #include <akonadi/itemfetchjob.h>
56 #include <akonadi/itemfetchscope.h>
57 
58 #include "akonadi/entityorderproxymodel.h"
59 #include <Akonadi/Notes/NoteUtils>
60 #include "akonadi_next/notecreatorandselector.h"
61 
62 // Grantlee
63 #include <grantlee/template.h>
64 #include <grantlee/engine.h>
65 #include <grantlee/context.h>
66 
67 // KDE
68 #include <KAction>
69 #include <KActionCollection>
70 #include <KBookmarkMenu>
71 #include <KFileDialog>
72 #include <KFind>
73 #include <KFindDialog>
74 #include <KLocalizedString>
75 #include <KMessageBox>
76 #include <KReplaceDialog>
77 #include <kselectionproxymodel.h>
78 #include <KStandardDirs>
79 #include <KGlobalSettings>
80 #include <KXMLGUIClient>
81 #include <KProcess>
82 #include <KPrintPreview>
83 
84 // KMime
85 #include <KMime/KMimeMessage>
86 
87 // KJots
88 #include "kjotsbookmarks.h"
89 #include "kjotssortproxymodel.h"
90 #include "kjotsmodel.h"
91 #include "kjotsedit.h"
92 #include "kjotstreeview.h"
93 #include "kjotsconfigdlg.h"
94 #include "kjotsreplacenextdialog.h"
95 #include "KJotsSettings.h"
96 #include "kjotslockjob.h"
97 
98 #include <kdebug.h>
99 
100 #include <memory>
101 #include "noteshared/attributes/notelockattribute.h"
102 #include "localresourcecreator.h"
103 #include <krandom.h>
104 #include "kjotsbrowser.h"
105 
106 #ifndef KDE_USE_FINAL
107 Q_DECLARE_METATYPE(QTextDocument*)
108 Q_DECLARE_METATYPE(QTextCursor)
109 #endif
110 using namespace Akonadi;
111 using namespace Grantlee;
112 
113 KJotsWidget::KJotsWidget( QWidget * parent, KXMLGUIClient *xmlGuiClient, Qt::WindowFlags f )
114  : QWidget( parent, f ), m_xmlGuiClient( xmlGuiClient )
115 {
116  Akonadi::Control::widgetNeedsAkonadi( this );
117 
118  KConfigGroup migrationCfg( KGlobal::config(), "General" );
119  const bool autoCreate = migrationCfg.readEntry( "AutoCreateResourceOnStart", true );
120  migrationCfg.writeEntry("AutoCreateResourceOnStart", autoCreate);
121  migrationCfg.sync();
122  if (autoCreate) {
123  LocalResourceCreator *creator = new LocalResourceCreator( this );
124  creator->createIfMissing();
125  }
126 
127  m_splitter = new QSplitter( this );
128 
129  m_splitter->setStretchFactor(1, 1);
130  m_splitter->setOpaqueResize( KGlobalSettings::opaqueResize() );
131 
132  QHBoxLayout *layout = new QHBoxLayout( this );
133  layout->setMargin( 0 );
134 
135  KStandardDirs KStd;
136  m_templateEngine = new Engine(this);
137  m_templateEngine->setPluginPaths( KStd.findDirs( "lib", QString() ) );
138 
139  m_loader = FileSystemTemplateLoader::Ptr( new FileSystemTemplateLoader() );
140  m_loader->setTemplateDirs( KStd.findDirs( "data", QLatin1String( "kjots/themes" ) ) );
141  m_loader->setTheme( QLatin1String( "default" ) );
142 
143  m_templateEngine->addTemplateLoader( m_loader );
144 
145  treeview = new KJotsTreeView( xmlGuiClient, m_splitter );
146 
147  ItemFetchScope scope;
148  scope.fetchFullPayload( true ); // Need to have full item when adding it to the internal data structure
149  scope.fetchAttribute< EntityDisplayAttribute >();
150  scope.fetchAttribute< NoteShared::NoteLockAttribute >();
151 
152  ChangeRecorder *monitor = new ChangeRecorder( this );
153  monitor->fetchCollection( true );
154  monitor->setItemFetchScope( scope );
155  monitor->setCollectionMonitored( Collection::root() );
156  monitor->setMimeTypeMonitored( Akonadi::NoteUtils::noteMimeType() );
157 
158  m_kjotsModel = new KJotsModel( monitor, this );
159 
160  m_sortProxyModel = new KJotsSortProxyModel( this );
161  m_sortProxyModel->setSourceModel( m_kjotsModel );
162 
163  m_orderProxy = new EntityOrderProxyModel( this );
164  m_orderProxy->setSourceModel( m_sortProxyModel );
165 
166  KConfigGroup cfg( KGlobal::config(), "KJotsEntityOrder" );
167 
168  m_orderProxy->setOrderConfig( cfg );
169 
170  treeview->setModel( m_orderProxy );
171  treeview->setSelectionMode( QAbstractItemView::ExtendedSelection );
172  treeview->setEditTriggers( QAbstractItemView::DoubleClicked );
173 
174  connect( treeview->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(selectionChanged(QItemSelection,QItemSelection)) );
175 
176  selProxy = new KSelectionProxyModel( treeview->selectionModel(), this );
177  selProxy->setSourceModel( treeview->model() );
178 
179  // TODO: Write a QAbstractItemView subclass to render kjots selection.
180  connect( selProxy, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(renderSelection()) );
181  connect( selProxy, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(renderSelection()) );
182  connect( selProxy, SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(renderSelection()) );
183 
184 
185  stackedWidget = new QStackedWidget( m_splitter );
186 
187  KActionCollection *actionCollection = xmlGuiClient->actionCollection();
188 
189  editor = new KJotsEdit( treeview->selectionModel(), stackedWidget );
190  editor->createActions( actionCollection );
191  stackedWidget->addWidget( editor );
192 
193  layout->addWidget( m_splitter );
194 
195  browser = new KJotsBrowser( treeview->selectionModel(), stackedWidget );
196  stackedWidget->addWidget( browser );
197  stackedWidget->setCurrentWidget( browser );
198 
199 
200  KAction *action;
201 
202  action = actionCollection->addAction( QLatin1String("go_next_book") );
203  action->setText( i18n( "Next Book" ) );
204  action->setIcon( KIcon( QLatin1String("go-down") ) );
205  action->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_D ) );
206  connect( action, SIGNAL(triggered()), SLOT(nextBook()) );
207  connect( this, SIGNAL(canGoNextBookChanged(bool)), action, SLOT(setEnabled(bool)) );
208 
209  action = actionCollection->addAction( QLatin1String("go_prev_book") );
210  action->setText( i18n( "Previous Book" ) );
211  action->setIcon( KIcon( QLatin1String("go-up") ) );
212  action->setShortcut( QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_D ) );
213  connect( action, SIGNAL(triggered()), SLOT(prevBook()) );
214  connect( this, SIGNAL(canGoPreviousBookChanged(bool)), action, SLOT(setEnabled(bool)) );
215 
216  action = actionCollection->addAction( QLatin1String("go_next_page") );
217  action->setText( i18n( "Next Page" ) );
218  action->setIcon( KIcon( QLatin1String("go-next") ) );
219  action->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_PageDown ) );
220  connect( action, SIGNAL(triggered()), SLOT(nextPage()));
221  connect( this, SIGNAL(canGoNextPageChanged(bool)), action, SLOT(setEnabled(bool)) );
222 
223  action = actionCollection->addAction( QLatin1String("go_prev_page") );
224  action->setText( i18n( "Previous Page" ) );
225  action->setIcon( KIcon( QLatin1String("go-previous") ) );
226  action->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_PageUp ) );
227  connect( action, SIGNAL(triggered()), SLOT(prevPage()) );
228  connect( this, SIGNAL(canGoPreviousPageChanged(bool)), action, SLOT(setEnabled(bool)) );
229 
230  action = actionCollection->addAction( QLatin1String("new_page") );
231  action->setText( i18n( "&New Page" ) );
232  action->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_N ) );
233  action->setIcon( KIcon( QLatin1String("document-new") ) );
234  connect( action, SIGNAL(triggered()), SLOT(newPage()) );
235 
236  action = actionCollection->addAction(QLatin1String("new_book"));
237  action->setText( i18n( "New &Book..." ) );
238  action->setShortcut( QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_N ) );
239  action->setIcon( KIcon( QLatin1String("address-book-new") ) );
240  connect( action, SIGNAL(triggered()), SLOT(newBook()) );
241 
242  action = actionCollection->addAction( QLatin1String("del_page") );
243  action->setText( i18n( "&Delete Page" ) );
244  action->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_Delete ) );
245  action->setIcon( KIcon( QLatin1String("edit-delete-page") ) );
246  connect( action, SIGNAL(triggered()), SLOT(deletePage()) );
247 
248  action = actionCollection->addAction( QLatin1String("del_folder") );
249  action->setText( i18n( "Delete Boo&k" ) );
250  action->setShortcut( QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_Delete ) );
251  action->setIcon( KIcon( QLatin1String("edit-delete") ) );
252  connect( action, SIGNAL(triggered()), SLOT(deleteBook()) );
253 
254  action = actionCollection->addAction( QLatin1String("del_mult") );
255  action->setText( i18n( "Delete Selected" ) );
256  action->setIcon( KIcon( QLatin1String("edit-delete") ) );
257  connect( action, SIGNAL(triggered()), SLOT(deleteMultiple()) );
258 
259  action = actionCollection->addAction( QLatin1String("manual_save") );
260  action->setText( i18n( "Manual Save" ) );
261  action->setIcon( KIcon( QLatin1String("document-save") ) );
262  action->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_S ) );
263 
264  action = actionCollection->addAction( QLatin1String("auto_bullet") );
265  action->setText( i18n( "Auto Bullets" ) );
266  action->setIcon( KIcon( QLatin1String("format-list-unordered") ) );
267  action->setCheckable( true );
268 
269  action = actionCollection->addAction( QLatin1String("auto_decimal") );
270  action->setText( i18n( "Auto Decimal List" ) );
271  action->setIcon( KIcon( QLatin1String("format-list-ordered") ) );
272  action->setCheckable( true );
273 
274  action = actionCollection->addAction( QLatin1String("manage_link") );
275  action->setText( i18n( "Link" ) );
276  action->setIcon( KIcon( QLatin1String("insert-link") ) );
277 
278  action = actionCollection->addAction( QLatin1String("insert_checkmark") );
279  action->setText( i18n( "Insert Checkmark" ) );
280  action->setIcon( KIcon( QLatin1String("checkmark") ) );
281  action->setEnabled( false );
282 
283  action = actionCollection->addAction( QLatin1String("rename_entry") );
284  action->setText( i18n( "Rename..." ) );
285  action->setIcon( KIcon( QLatin1String("edit-rename") ) );
286  action->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_M ) );
287 
288  action = actionCollection->addAction( QLatin1String("insert_date") );
289  action->setText( i18n( "Insert Date" ) );
290  action->setShortcut( QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_I ) );
291  action->setIcon( KIcon( QLatin1String("view-calendar-time-spent") ) );
292 
293  action = actionCollection->addAction( QLatin1String("change_color") );
294  action->setIcon( KIcon( QLatin1String("format-fill-color") ) );
295  action->setText( i18n( "Change Color..." ) );
296 
297  action = actionCollection->addAction( QLatin1String("copy_link_address") );
298  action->setText( i18n( "Copy Link Address" ) );
299 
300  action = actionCollection->addAction( QLatin1String("lock") );
301  action->setText(i18n( "Lock Selected" ) );
302  action->setIcon( KIcon( QLatin1String("emblem-locked") ) );
303  connect( action, SIGNAL(triggered()), SLOT(actionLock()) );
304 
305  action = actionCollection->addAction( QLatin1String("unlock") );
306  action->setText( i18n( "Unlock Selected" ) );
307  action->setIcon( KIcon( QLatin1String("emblem-unlocked") ) );
308  connect( action, SIGNAL(triggered()), SLOT(actionUnlock()) );
309 
310  action = actionCollection->addAction( QLatin1String("sort_children_alpha") );
311  action->setText( i18n( "Sort children alphabetically" ) );
312  connect( action, SIGNAL(triggered()), SLOT(actionSortChildrenAlpha()) );
313 
314  action = actionCollection->addAction( QLatin1String("sort_children_by_date") );
315  action->setText( i18n( "Sort children by creation date" ) );
316  connect( action, SIGNAL(triggered()), SLOT(actionSortChildrenByDate()) );
317 
318  action = KStandardAction::cut( editor, SLOT(cut()), actionCollection );
319  connect( editor, SIGNAL(copyAvailable(bool)), action, SLOT(setEnabled(bool)) );
320  action->setEnabled( false );
321 
322  action = KStandardAction::copy( this, SLOT(copy()), actionCollection );
323  connect( editor, SIGNAL(copyAvailable(bool)), action, SLOT(setEnabled(bool)) );
324  connect( browser, SIGNAL(copyAvailable(bool)), action, SLOT(setEnabled(bool)) );
325  action->setEnabled( false );
326 
327  KStandardAction::pasteText( editor, SLOT(paste()), actionCollection );
328 
329  KStandardAction::undo( editor, SLOT(undo()), actionCollection );
330  KStandardAction::redo( editor, SLOT(redo()), actionCollection );
331  KStandardAction::selectAll( editor, SLOT(selectAll()), actionCollection );
332 
333  action = actionCollection->addAction( QLatin1String("copyIntoTitle") );
334  action->setText( i18n( "Copy &into Page Title" ) );
335  action->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_T ) );
336  action->setIcon( KIcon( QLatin1String("edit-copy") ) );
337  connect( action, SIGNAL(triggered()), SLOT(copySelectionToTitle()) );
338  connect( editor, SIGNAL(copyAvailable(bool)), action, SLOT(setEnabled(bool)) );
339  action->setEnabled( false );
340 
341  action = actionCollection->addAction( QLatin1String("paste_plain_text") );
342  action->setText( i18nc( "@action Paste the text in the clipboard without rich text formatting.", "Paste Plain Text" ) );
343  connect( action, SIGNAL(triggered()), editor, SLOT(pastePlainText()) );
344 
345  KStandardAction::preferences( this, SLOT(configure()), actionCollection );
346 
347  bookmarkMenu = actionCollection->add<KActionMenu>( QLatin1String("bookmarks") );
348  bookmarkMenu->setText( i18n( "&Bookmarks" ) );
349  KJotsBookmarks* bookmarks = new KJotsBookmarks( treeview );
350  /*KBookmarkMenu *bmm =*/ new KBookmarkMenu(
351  KBookmarkManager::managerForFile( KStandardDirs::locateLocal( "data",QLatin1String("kjots/bookmarks.xml") ), QLatin1String("kjots") ),
352  bookmarks, bookmarkMenu->menu(), actionCollection );
353 
354  // "Add bookmark" and "make text bold" actions have conflicting shortcuts (ctrl + b)
355  // Make add_bookmark use ctrl+shift+b to resolve that.
356  KAction *bm_action = qobject_cast<KAction *>(actionCollection->action(QLatin1String("add_bookmark")));
357  Q_ASSERT(bm_action);
358  bm_action->setShortcut( Qt::CTRL + Qt::SHIFT + Qt::Key_B );
359 
360  KStandardAction::find( this, SLOT(onShowSearch()), actionCollection );
361  action = KStandardAction::findNext( this, SLOT(onRepeatSearch()), actionCollection );
362  action->setEnabled(false);
363  KStandardAction::replace( this, SLOT(onShowReplace()), actionCollection );
364 
365  action = actionCollection->addAction( QLatin1String("save_to") );
366  action->setText( i18n( "Rename..." ) );
367  action->setIcon( KIcon( QLatin1String("edit-rename") ) );
368  action->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_M ) );
369 
370  KActionMenu *exportMenu = actionCollection->add<KActionMenu>( QLatin1String("save_to") );
371  exportMenu->setText( i18n( "Export" ) );
372  exportMenu->setIcon( KIcon( QLatin1String("document-export") ) );
373 
374  action = actionCollection->addAction( QLatin1String("save_to_ascii") );
375  action->setText( i18n( "To Text File..." ) );
376  action->setIcon( KIcon( QLatin1String("text-plain") ) );
377  connect( action, SIGNAL(triggered()), SLOT(exportSelectionToPlainText()) );
378  exportMenu->menu()->addAction( action );
379 
380  action = actionCollection->addAction( QLatin1String("save_to_html") );
381  action->setText( i18n( "To HTML File..." ) );
382  action->setIcon( KIcon( QLatin1String("text-html") ) );
383  connect( action, SIGNAL(triggered()), SLOT(exportSelectionToHtml()) );
384  exportMenu->menu()->addAction( action );
385 
386  action = actionCollection->addAction( QLatin1String("save_to_book") );
387  action->setText( i18n( "To Book File..." ) );
388  action->setIcon( KIcon( QLatin1String("x-office-address-book") ) );
389  connect( action, SIGNAL(triggered()), SLOT(exportSelectionToXml()) );
390  exportMenu->menu()->addAction( action );
391 
392  KStandardAction::print(this, SLOT(printSelection()), actionCollection);
393  KStandardAction::printPreview(this, SLOT(printPreviewSelection()), actionCollection);
394 
395  if ( !KJotsSettings::splitterSizes().isEmpty() )
396  {
397  m_splitter->setSizes( KJotsSettings::splitterSizes() );
398  }
399 
400  QTimer::singleShot( 0, this, SLOT(delayedInitialization()) );
401 
402  connect( treeview->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(updateMenu()) );
403  connect( treeview->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(updateCaption()) );
404 
405  connect( m_kjotsModel, SIGNAL(modelAboutToBeReset()), SLOT(saveState()));
406  connect( m_kjotsModel, SIGNAL(modelReset()), SLOT(restoreState()));
407 
408  restoreState();
409 
410  QDBusConnection::sessionBus().registerObject( QLatin1String("/KJotsWidget"), this, QDBusConnection::ExportScriptableContents );
411 }
412 
413 KJotsWidget::~KJotsWidget()
414 {
415  saveState();
416 }
417 
418 void KJotsWidget::restoreState()
419 {
420  ETMViewStateSaver *saver = new ETMViewStateSaver;
421  saver->setView( treeview );
422  KConfigGroup cfg( KGlobal::config(), "TreeState" );
423  saver->restoreState( cfg );
424 }
425 
426 void KJotsWidget::saveState()
427 {
428  ETMViewStateSaver saver;
429  saver.setView( treeview );
430  KConfigGroup cfg( KGlobal::config(), "TreeState" );
431  saver.saveState( cfg );
432  cfg.sync();
433 }
434 
435 void KJotsWidget::delayedInitialization()
436 {
437  migrateNoteData( QLatin1String("kjotsmigrator") );
438  // Disable nigration of data from KNotes as that app still exists in 4.5.
439 // migrateNoteData( "kres-migrator", "notes" );
440 
441  //TODO: Save previous searches in settings file?
442  searchDialog = new KFindDialog ( this, 0, QStringList(), false );
443  QGridLayout *layout = new QGridLayout(searchDialog->findExtension());
444  layout->setMargin(0);
445  searchAllPages = new QCheckBox(i18n("Search all pages"), searchDialog->findExtension());
446  layout->addWidget(searchAllPages, 0, 0);
447 
448  connect(searchDialog, SIGNAL(okClicked()), this, SLOT(onStartSearch()) );
449  connect(searchDialog, SIGNAL(cancelClicked()), this, SLOT(onEndSearch()) );
450  connect(treeview->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(onUpdateSearch()) );
451  connect(searchDialog, SIGNAL(optionsChanged()), SLOT(onUpdateSearch()) );
452  connect(searchAllPages, SIGNAL(stateChanged(int)), SLOT(onUpdateSearch()) );
453 
454  replaceDialog = new KReplaceDialog ( this, 0, searchHistory, replaceHistory, false );
455  QGridLayout *layout2 = new QGridLayout(replaceDialog->findExtension());
456  layout2->setMargin(0);
457  replaceAllPages = new QCheckBox(i18n("Search all pages"), replaceDialog->findExtension());
458  layout2->addWidget(replaceAllPages, 0, 0);
459 
460  connect(replaceDialog, SIGNAL(okClicked()), this, SLOT(onStartReplace()) );
461  connect(replaceDialog, SIGNAL(cancelClicked()), this, SLOT(onEndReplace()) );
462  connect(replaceDialog, SIGNAL(optionsChanged()), SLOT(onUpdateReplace()) );
463  connect(replaceAllPages, SIGNAL(stateChanged(int)), SLOT(onUpdateReplace()) );
464 
465  // Actions are enabled or disabled based on whether the selection is a single page, a single book
466  // multiple selections, or no selection.
467  //
468  // The entryActions are enabled for all single pages and single books, and the multiselectionActions
469  // are enabled when the user has made multiple selections.
470  //
471  // Some actions are in neither (eg, new book) and are available even when there is no selection.
472  //
473  // Some actions are in both, so that they are available for valid selections, but not available
474  // for invalid selections (eg, print/find are disabled when there is no selection)
475 
476  KActionCollection *actionCollection = m_xmlGuiClient->actionCollection();
477 
478  // Actions for a single item selection.
479  entryActions.insert( actionCollection->action(QLatin1String(KStandardAction::name(KStandardAction::Find))) );
480  entryActions.insert( actionCollection->action(QLatin1String(KStandardAction::name(KStandardAction::Print))) );
481  entryActions.insert( actionCollection->action(QLatin1String("rename_entry")) );
482  entryActions.insert( actionCollection->action(QLatin1String("change_color")) );
483  entryActions.insert( actionCollection->action(QLatin1String("save_to")) );
484  entryActions.insert( actionCollection->action(QLatin1String("copy_link_address")) );
485 
486  // Actions that are used only when a page is selected.
487  pageActions.insert( actionCollection->action(QLatin1String(KStandardAction::name(KStandardAction::Cut))) );
488  pageActions.insert( actionCollection->action(QLatin1String(KStandardAction::name(KStandardAction::Paste))) );
489  pageActions.insert( actionCollection->action(QLatin1String(KStandardAction::name(KStandardAction::Replace))) );
490  pageActions.insert( actionCollection->action(QLatin1String("del_page")) );
491  pageActions.insert( actionCollection->action(QLatin1String("insert_date")) );
492  pageActions.insert( actionCollection->action(QLatin1String("auto_bullet")) );
493  pageActions.insert( actionCollection->action(QLatin1String("auto_decimal")) );
494  pageActions.insert( actionCollection->action(QLatin1String("manage_link")) );
495  pageActions.insert( actionCollection->action(QLatin1String("insert_checkmark")) );
496 
497  // Actions that are used only when a book is selected.
498  bookActions.insert( actionCollection->action(QLatin1String("save_to_book")) );
499  bookActions.insert( actionCollection->action(QLatin1String("del_folder")) );
500  bookActions.insert( actionCollection->action(QLatin1String("sort_children_alpha")) );
501  bookActions.insert( actionCollection->action(QLatin1String("sort_children_by_date")) );
502 
503  // Actions that are used when multiple items are selected.
504  multiselectionActions.insert( actionCollection->action(QLatin1String(KStandardAction::name(KStandardAction::Find))) );
505  multiselectionActions.insert( actionCollection->action(QLatin1String(KStandardAction::name(KStandardAction::Print))));
506  multiselectionActions.insert( actionCollection->action(QLatin1String("del_mult")) );
507  multiselectionActions.insert( actionCollection->action(QLatin1String("save_to")) );
508  multiselectionActions.insert( actionCollection->action(QLatin1String("change_color")) );
509 
510  m_autosaveTimer = new QTimer(this);
511  updateConfiguration();
512 
513  connect(m_autosaveTimer, SIGNAL(timeout()), editor, SLOT(savePage()));
514  connect(treeview->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), m_autosaveTimer, SLOT(start()) );
515 
516  treeview->delayedInitialization();
517  editor->delayedInitialization( m_xmlGuiClient->actionCollection() );
518  browser->delayedInitialization();
519 
520 
521  connect( treeview->itemDelegate(), SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
522  SLOT(bookshelfEditItemFinished(QWidget*,QAbstractItemDelegate::EndEditHint)) );
523 
524  connect( editor, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
525  SLOT(currentCharFormatChanged(QTextCharFormat)) );
526  updateMenu();
527 }
528 
529 void KJotsWidget::bookshelfEditItemFinished( QWidget *, QAbstractItemDelegate::EndEditHint )
530 {
531  // Make sure the editor gets focus again after naming a new book/page.
532  activeEditor()->setFocus();
533 }
534 
535 void KJotsWidget::currentCharFormatChanged(const QTextCharFormat & fmt)
536 {
537  QString selectedAnchor = fmt.anchorHref();
538  if (selectedAnchor != activeAnchor)
539  {
540  activeAnchor = selectedAnchor;
541  if (!selectedAnchor.isEmpty())
542  {
543  QTextCursor c(editor->textCursor());
544  editor->selectLinkText(&c);
545  QString selectedText = c.selectedText();
546  if (!selectedText.isEmpty())
547  {
548  emit activeAnchorChanged(selectedAnchor, selectedText);
549  }
550  } else {
551  emit activeAnchorChanged(QString(), QString());
552  }
553  }
554 }
555 
556 void KJotsWidget::migrateNoteData( const QString &migrator, const QString &type )
557 {
558  // Akonadi migration
559  KConfig config( migrator + QLatin1String("rc") );
560  KConfigGroup migrationCfg( &config, "Migration" );
561  const bool enabled = migrationCfg.readEntry( "Enabled", true );
562  const bool completed = migrationCfg.readEntry( "Completed", false );
563  const int currentVersion = migrationCfg.readEntry( "Version", 0 );
564  const int targetVersion = migrationCfg.readEntry( "TargetVersion", 1 );
565  if ( enabled && !completed && currentVersion < targetVersion ) {
566  kDebug() << "Performing Akonadi migration. Good luck!";
567  KProcess proc;
568  QStringList args = QStringList() << QLatin1String("--interactive-on-change");
569  if ( !type.isEmpty() )
570  args << QLatin1String("--type") << type;
571 
572  const QString path = KStandardDirs::findExe( migrator );
573  proc.setProgram( path, args );
574  proc.start();
575  bool result = proc.waitForStarted();
576  if ( result ) {
577  result = proc.waitForFinished();
578  }
579  if ( result && proc.exitCode() == 0 ) {
580  kDebug() << "Akonadi migration has been successful";
581  } else {
582  // exit code 1 means it is already running, so we are probably called by a migrator instance
583  kError() << "Akonadi migration failed!";
584  kError() << "command was: " << proc.program();
585  kError() << "exit code: " << proc.exitCode();
586  kError() << "stdout: " << proc.readAllStandardOutput();
587  kError() << "stderr: " << proc.readAllStandardError();
588  }
589  migrationCfg.writeEntry( "Version", targetVersion );
590  migrationCfg.writeEntry( "Completed", true );
591  migrationCfg.sync();
592  }
593 }
594 
595 inline QTextEdit* KJotsWidget::activeEditor() {
596  if ( browser->isVisible() ) {
597  return browser;
598  } else {
599  return editor;
600  }
601 }
602 
603 void KJotsWidget::updateMenu()
604 {
605  QModelIndexList selection = treeview->selectionModel()->selectedRows();
606  int selectionSize = selection.size();
607 
608  if ( !selectionSize ) {
609  // no (meaningful?) selection
610  foreach ( QAction* action, multiselectionActions )
611  action->setEnabled(false);
612  foreach ( QAction* action, entryActions )
613  action->setEnabled(false);
614  foreach ( QAction* action, bookActions )
615  action->setEnabled(false);
616  foreach ( QAction* action, pageActions )
617  action->setEnabled(false);
618  editor->setActionsEnabled( false );
619  } else if ( selectionSize > 1 ) {
620  foreach ( QAction* action, entryActions )
621  action->setEnabled(false);
622  foreach ( QAction* action, bookActions )
623  action->setEnabled(false);
624  foreach ( QAction* action, pageActions )
625  action->setEnabled(false);
626  foreach ( QAction* action, multiselectionActions )
627  action->setEnabled(true);
628 
629  editor->setActionsEnabled( false );
630  } else {
631 
632  foreach ( QAction* action, multiselectionActions )
633  action->setEnabled(false);
634  foreach ( QAction* action, entryActions )
635  action->setEnabled(true);
636 
637  QModelIndex idx = selection.at( 0 );
638 
639  Collection col = idx.data( KJotsModel::CollectionRole ).value<Collection>();
640  if ( col.isValid() ) {
641  foreach ( QAction* action, pageActions )
642  action->setEnabled(false);
643  const bool colIsRootCollection = ( col.parentCollection() == Collection::root() );
644  foreach ( QAction* action, bookActions ) {
645  if (action->objectName() == QLatin1String("del_folder") && colIsRootCollection ) {
646  action->setEnabled( false );
647  } else {
648  action->setEnabled( true );
649  }
650 
651  }
652 
653  editor->setActionsEnabled( false );
654  } else {
655  foreach ( QAction* action, pageActions ) {
656  if (action->objectName() == QLatin1String(name( KStandardAction::Cut )) ) {
657  action->setEnabled( activeEditor()->textCursor().hasSelection() );
658  } else {
659  action->setEnabled( true );
660  }
661  }
662  foreach ( QAction* action, bookActions )
663  action->setEnabled( false );
664  editor->setActionsEnabled( true );
665  }
666  }
667 }
668 
669 void KJotsWidget::copy() {
670  activeEditor()->copy();
671 }
672 
673 void KJotsWidget::configure()
674 {
675  // create a new preferences dialog...
676  KJotsConfigDlg *dialog = new KJotsConfigDlg( i18n( "Settings" ), this );
677  connect( dialog, SIGNAL(configCommitted()), SLOT(updateConfiguration()) );
678  dialog->show();
679 }
680 
681 void KJotsWidget::updateConfiguration()
682 {
683  if (KJotsSettings::autoSave())
684  {
685  m_autosaveTimer->setInterval(KJotsSettings::autoSaveInterval()*1000*60);
686  m_autosaveTimer->start();
687  } else
688  m_autosaveTimer->stop();
689 }
690 
691 void KJotsWidget::copySelectionToTitle()
692 {
693  QString newTitle( editor->textCursor().selectedText() );
694 
695  if ( !newTitle.isEmpty() ) {
696 
697  QModelIndexList rows = treeview->selectionModel()->selectedRows();
698 
699  if ( rows.size() != 1 )
700  return;
701 
702  QModelIndex idx = rows.at( 0 );
703 
704  treeview->model()->setData( idx, newTitle );
705  }
706 }
707 
708 void KJotsWidget::deleteMultiple()
709 {
710  QModelIndexList selectedRows = treeview->selectionModel()->selectedRows();
711 
712  if ( KMessageBox::questionYesNo( this,
713  i18n( "Do you really want to delete all selected books and pages?" ),
714  i18n("Delete?"), KStandardGuiItem::del(), KStandardGuiItem::cancel(),
715  QString(), KMessageBox::Dangerous ) != KMessageBox::Yes )
716  return;
717 
718  foreach ( const QModelIndex &index, selectedRows ) {
719  bool ok;
720  qlonglong id = index.data( EntityTreeModel::ItemIdRole ).toLongLong(&ok);
721  Q_ASSERT(ok);
722  if ( id >= 0 )
723  {
724  new ItemDeleteJob( Item( id ), this );
725  }
726  else {
727  id = index.data( EntityTreeModel::CollectionIdRole ).toLongLong(&ok);
728  Q_ASSERT(ok);
729  if ( id >= 0 )
730  new CollectionDeleteJob( Collection( id ), this );
731  }
732  }
733 }
734 
735 void KJotsWidget::deletePage()
736 {
737  QModelIndexList selectedRows = treeview->selectionModel()->selectedRows();
738 
739  if ( selectedRows.size() != 1 )
740  return;
741 
742  const QModelIndex idx = selectedRows.at( 0 );
743  Item item = idx.data( EntityTreeModel::ItemRole ).value<Item>();
744 
745  if ( !item.isValid() )
746  return;
747 
748  if( item.hasAttribute<NoteShared::NoteLockAttribute>() ) {
749 
750  KMessageBox::information(topLevelWidget(),
751  i18n("This page is locked. You can only delete it when you first unlock it."),
752  i18n("Item is locked"));
753  return;
754  }
755 
756  if ( KMessageBox::warningContinueCancel(topLevelWidget(),
757  i18nc("remove the page, by title", "<qt>Are you sure you want to delete the page <strong>%1</strong>?</qt>", idx.data().toString()),
758  i18n("Delete"), KStandardGuiItem::del(), KStandardGuiItem::cancel(), QLatin1String("DeletePageWarning")) == KMessageBox::Cancel) {
759  return;
760  }
761 
762  (void) new Akonadi::ItemDeleteJob( item, this );
763 }
764 
765 void KJotsWidget::deleteBook()
766 {
767  QModelIndexList selectedRows = treeview->selectionModel()->selectedRows();
768 
769  if ( selectedRows.size() != 1 )
770  return;
771 
772  const QModelIndex idx = selectedRows.at( 0 );
773  Collection col = idx.data( EntityTreeModel::CollectionRole ).value<Collection>();
774 
775  if ( !col.isValid() )
776  return;
777 
778  if ( col.parentCollection() == Collection::root() )
779  return;
780 
781  if( col.hasAttribute<NoteShared::NoteLockAttribute>() ) {
782 
783  KMessageBox::information(topLevelWidget(),
784  i18n("This book is locked. You can only delete it when you first unlock it."),
785  i18n("Item is locked"));
786  return;
787  }
788  if ( KMessageBox::warningContinueCancel(topLevelWidget(),
789  i18nc("remove the book, by title", "<qt>Are you sure you want to delete the book <strong>%1</strong>?</qt>", idx.data().toString()),
790  i18n("Delete"), KStandardGuiItem::del(), KStandardGuiItem::cancel(), QLatin1String("DeleteBookWarning")) == KMessageBox::Cancel) {
791  return;
792  }
793 
794  (void) new Akonadi::CollectionDeleteJob( col, this );
795 }
796 
797 void KJotsWidget::newBook()
798 {
799  QModelIndexList selectedRows = treeview->selectionModel()->selectedRows();
800 
801  if ( selectedRows.size() != 1 )
802  return;
803 
804  Collection col = selectedRows.at( 0 ).data( EntityTreeModel::CollectionRole ).value<Collection>();
805 
806  if ( !col.isValid() )
807  return;
808 
809  Collection newCollection;
810  newCollection.setParentCollection( col );
811 
812  QString title = i18nc( "The default name for new books.", "New Book" );
813  newCollection.setName( KRandom::randomString( 10 ) );
814  newCollection.setContentMimeTypes( QStringList() << Akonadi::Collection::mimeType() << Akonadi::NoteUtils::noteMimeType() );
815 
816  Akonadi::EntityDisplayAttribute *eda = new Akonadi::EntityDisplayAttribute();
817  eda->setIconName( QLatin1String("x-office-address-book") );
818  eda->setDisplayName( title );
819  newCollection.addAttribute( eda );
820 
821  Akonadi::CollectionCreateJob *job = new Akonadi::CollectionCreateJob( newCollection );
822  connect( job, SIGNAL(result(KJob*)), this, SLOT(newBookResult(KJob*)) );
823 }
824 
825 void KJotsWidget::newPage()
826 {
827  QModelIndexList selectedRows = treeview->selectionModel()->selectedRows();
828 
829  if ( selectedRows.size() != 1 )
830  return;
831 
832  Item item = selectedRows.at( 0 ).data( EntityTreeModel::ItemRole ).value<Item>();
833 
834  Collection col;
835  if ( item.isValid() )
836  {
837  col = selectedRows.at( 0 ).data( EntityTreeModel::ParentCollectionRole ).value<Collection>();
838  } else {
839  col = selectedRows.at( 0 ).data( EntityTreeModel::CollectionRole ).value<Collection>();
840  }
841 
842  if ( !col.isValid() )
843  return;
844  doCreateNewPage(col);
845 }
846 
847 void KJotsWidget::doCreateNewPage(const Collection &collection)
848 {
849  Akonotes::NoteCreatorAndSelector *creatorAndSelector = new Akonotes::NoteCreatorAndSelector(treeview->selectionModel());
850  creatorAndSelector->createNote(collection);
851 }
852 
853 void KJotsWidget::newPageResult( KJob* job )
854 {
855  if ( job->error() )
856  kDebug() << job->errorString();
857 }
858 
859 void KJotsWidget::newBookResult( KJob* job )
860 {
861  if ( job->error() ) {
862  kDebug() << job->errorString();
863  return;
864  }
865  Akonadi::CollectionCreateJob *createJob = qobject_cast<Akonadi::CollectionCreateJob*>(job);
866  if ( !createJob )
867  return;
868  const Collection collection = createJob->collection();
869  if ( !collection.isValid() )
870  return;
871 
872  doCreateNewPage(collection);
873 }
874 
875 QString KJotsWidget::renderSelectionToHtml()
876 {
877  QHash<QString, QVariant> hash;
878 
879  QList<QVariant> objectList;
880 
881  const int rows = selProxy->rowCount();
882  const int column = 0;
883  for ( int row = 0; row < rows; ++row )
884  {
885  QModelIndex idx = selProxy->index( row, column, QModelIndex() );
886 
887  QObject *obj = idx.data(KJotsModel::GrantleeObjectRole).value<QObject*>();
888  KJotsEntity *kjotsEntity = qobject_cast<KJotsEntity*>(obj);
889  kjotsEntity->setIndex(idx);
890  objectList << QVariant::fromValue(static_cast<QObject *>(kjotsEntity));
891  }
892 
893  hash.insert( QLatin1String( "entities" ), objectList);
894  hash.insert( QLatin1String( "i18n_TABLE_OF_CONTENTS" ),
895  i18nc("Header for 'Table of contents' section of rendered output", "Table of contents") );
896  Context c(hash);
897 
898  Template t = m_templateEngine->loadByName( QLatin1String( "template.html" ) );
899 
900  QString result = t->render(&c);
901 
902  // TODO: handle errors.
903  return result;
904 }
905 
906 QString KJotsWidget::renderSelectionToPlainText()
907 {
908  QHash<QString, QVariant> hash;
909 
910  QList<QVariant> objectList;
911 
912  const int rows = selProxy->rowCount();
913  const int column = 0;
914  for ( int row = 0; row < rows; ++row )
915  {
916  QModelIndex idx = selProxy->index( row, column, QModelIndex() );
917 
918  QObject *obj = idx.data(KJotsModel::GrantleeObjectRole).value<QObject*>();
919  KJotsEntity *kjotsEntity = qobject_cast<KJotsEntity*>(obj);
920  kjotsEntity->setIndex(idx);
921  objectList << QVariant::fromValue(static_cast<QObject *>(kjotsEntity));
922  }
923 
924  hash.insert( QLatin1String( "entities" ), objectList);
925  hash.insert( QLatin1String( "i18n_TABLE_OF_CONTENTS" ),
926  i18nc("Header for 'Table of contents' section of rendered output", "Table of contents") );
927  Context c(hash);
928 
929  Template t = m_templateEngine->loadByName( QLatin1String( "template.txt" ) );
930 
931  QString result = t->render(&c);
932 
933  // TODO: handle errors.
934  return result;
935 }
936 
937 
938 QString KJotsWidget::renderSelectionToXml()
939 {
940  QHash<QString, QVariant> hash;
941 
942  QList<QVariant> objectList;
943 
944  const int rows = selProxy->rowCount();
945  const int column = 0;
946  for ( int row = 0; row < rows; ++row )
947  {
948  QModelIndex idx = selProxy->index( row, column, QModelIndex() );
949 
950  QObject *obj = idx.data(KJotsModel::GrantleeObjectRole).value<QObject*>();
951  KJotsEntity *kjotsEntity = qobject_cast<KJotsEntity*>(obj);
952  kjotsEntity->setIndex(idx);
953  objectList << QVariant::fromValue(static_cast<QObject *>(kjotsEntity));
954  }
955 
956  hash.insert( QLatin1String( "entities" ), objectList);
957  Context c(hash);
958 
959  QString currentTheme = m_loader->themeName();
960  m_loader->setTheme( QLatin1String("xml_output") );
961  Template t = m_templateEngine->loadByName( QLatin1String( "template.xml" ) );
962 
963  QString result = t->render(&c);
964 
965  m_loader->setTheme(currentTheme);
966  return result;
967 }
968 
969 void KJotsWidget::renderSelection()
970 {
971  const int rows = selProxy->rowCount();
972 
973  // If the selection is a single page, present it for editing...
974  if (rows == 1)
975  {
976  QModelIndex idx = selProxy->index( 0, 0, QModelIndex());
977 
978  QTextDocument *document = idx.data( KJotsModel::DocumentRole ).value<QTextDocument*>();
979 
980  if ( document )
981  {
982  editor->setDocument( document );
983  QTextCursor textCursor = document->property( "textCursor" ).value<QTextCursor>();
984  if ( !textCursor.isNull() )
985  editor->setTextCursor( textCursor );
986  stackedWidget->setCurrentWidget( editor );
987  editor->setFocus();
988  return;
989  } // else fallthrough
990  }
991 
992  // ... Otherwise, render the selection read-only.
993 
994  QTextDocument doc;
995  QTextCursor cursor(&doc);
996 
997  browser->setHtml( renderSelectionToHtml() );
998  stackedWidget->setCurrentWidget( browser );
999 }
1000 
1001 QString KJotsWidget::getThemeFromUser()
1002 {
1003  return QString();
1004 #if 0
1005  bool ok;
1006  QString text = QInputDialog::getText(this, i18n("Change Theme"),
1007  tr("Theme name:"), QLineEdit::Normal,
1008  m_loader->themeName(), &ok);
1009  if (!ok || text.isEmpty())
1010  {
1011  return QLatin1String("default");
1012  }
1013 
1014  return text;
1015 #endif
1016 }
1017 
1018 
1019 void KJotsWidget::changeTheme()
1020 {
1021 #if 0
1022  m_loader->setTheme(getThemeFromUser());
1023  renderSelection();
1024 #endif
1025 }
1026 
1027 void KJotsWidget::exportSelectionToHtml()
1028 {
1029  QString currentTheme = m_loader->themeName();
1030  QString themeName = getThemeFromUser();
1031  if (themeName.isEmpty())
1032  {
1033  themeName = QLatin1String( "default" );
1034  }
1035  m_loader->setTheme(themeName);
1036 
1037  QString filename = KFileDialog::getSaveFileName();
1038  if (!filename.isEmpty())
1039  {
1040  QFile exportFile ( filename );
1041  if ( !exportFile.open(QIODevice::WriteOnly | QIODevice::Text) ) {
1042  m_loader->setTheme(currentTheme);
1043  KMessageBox::error(0, i18n("<qt>Error opening internal file.</qt>"));
1044  return;
1045  }
1046  exportFile.write(renderSelectionToHtml().toUtf8());
1047 
1048  exportFile.close();
1049  }
1050  m_loader->setTheme(currentTheme);
1051 }
1052 
1053 void KJotsWidget::exportSelectionToPlainText()
1054 {
1055  QString currentTheme = m_loader->themeName();
1056 
1057  m_loader->setTheme( QLatin1String("plain_text") );
1058 
1059  QString filename = KFileDialog::getSaveFileName();
1060  if (!filename.isEmpty())
1061  {
1062  QFile exportFile ( filename );
1063  if ( !exportFile.open(QIODevice::WriteOnly | QIODevice::Text) ) {
1064  m_loader->setTheme(currentTheme);
1065  KMessageBox::error(0, i18n("<qt>Error opening internal file.</qt>"));
1066  return;
1067  }
1068  exportFile.write(renderSelectionToPlainText().toUtf8());
1069 
1070  exportFile.close();
1071  }
1072  m_loader->setTheme(currentTheme);
1073 }
1074 
1075 void KJotsWidget::exportSelectionToXml()
1076 {
1077  QString currentTheme = m_loader->themeName();
1078 
1079  m_loader->setTheme( QLatin1String("xml_output") );
1080 
1081  QString filename = KFileDialog::getSaveFileName();
1082  if (!filename.isEmpty())
1083  {
1084  QFile exportFile ( filename );
1085  if ( !exportFile.open(QIODevice::WriteOnly | QIODevice::Text) ) {
1086  m_loader->setTheme(currentTheme);
1087  KMessageBox::error(0, i18n("<qt>Error opening internal file.</qt>"));
1088  return;
1089  }
1090  exportFile.write(renderSelectionToXml().toUtf8());
1091 
1092  exportFile.close();
1093  }
1094  m_loader->setTheme(currentTheme);
1095 }
1096 
1097 void KJotsWidget::printPreviewSelection()
1098 {
1099  QPrinter printer(QPrinter::HighResolution);
1100  printer.setDocName(QLatin1String("KJots_Print"));
1101  printer.setFullPage(false);
1102  printer.setCreator(QLatin1String("KJots"));
1103  KPrintPreview previewdlg( &printer, 0 );
1104  print(printer);
1105  previewdlg.exec();
1106 }
1107 
1108 void KJotsWidget::printSelection()
1109 {
1110 
1111  QPrinter printer(QPrinter::HighResolution);
1112  printer.setDocName(QLatin1String("KJots_Print"));
1113  printer.setFullPage(false);
1114  printer.setCreator(QLatin1String("KJots"));
1115  //Not supported in Qt?
1116  //printer->setPageSelection(QPrinter::ApplicationSide);
1117 
1118  //KPrinter::pageList() only works with ApplicationSide. ApplicationSide
1119  //requires min/max pages. How am I supposed to tell how many pages there
1120  //are before I setup the printer?
1121 
1122 
1123  QPointer<QPrintDialog> printDialog = new QPrintDialog(&printer, this);
1124 
1125  QAbstractPrintDialog::PrintDialogOptions options = printDialog->enabledOptions();
1126  options &= ~QAbstractPrintDialog::PrintPageRange;
1127  if (activeEditor()->textCursor().hasSelection())
1128  options |= QAbstractPrintDialog::PrintSelection;
1129  printDialog->setEnabledOptions(options);
1130 
1131  printDialog->setWindowTitle(i18n("Send To Printer"));
1132  if (printDialog->exec() == QDialog::Accepted) {
1133  print(printer);
1134  }
1135  delete printDialog;
1136 }
1137 
1138 void KJotsWidget::print(QPrinter &printer)
1139 {
1140  QTextDocument printDocument;
1141  if ( printer.printRange() == QPrinter::Selection )
1142  {
1143  printDocument.setHtml( activeEditor()->textCursor().selection().toHtml() );
1144  } else {
1145  //QTextCursor printCursor ( &printDocument );
1146  QString currentTheme = m_loader->themeName();
1147  m_loader->setTheme( QLatin1String("default") );
1148  printDocument.setHtml( renderSelectionToHtml() );
1149  m_loader->setTheme( currentTheme );
1150  }
1151 
1152  QPainter p(&printer);
1153 
1154  // Check that there is a valid device to print to.
1155  if (p.isActive()) {
1156  QTextDocument *doc = &printDocument;
1157 
1158  QRectF body = QRectF(QPointF(0, 0), doc->pageSize());
1159  QPointF pageNumberPos;
1160 
1161  QAbstractTextDocumentLayout *layout = doc->documentLayout();
1162  layout->setPaintDevice(p.device());
1163 
1164  const int dpiy = p.device()->logicalDpiY();
1165 
1166  const int margin = (int) ((2/2.54)*dpiy); // 2 cm margins
1167  QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
1168  fmt.setMargin(margin);
1169  doc->rootFrame()->setFrameFormat(fmt);
1170 
1171  body = QRectF(0, 0, p.device()->width(), p.device()->height());
1172  pageNumberPos = QPointF(body.width() - margin,
1173  body.height() - margin
1174  + QFontMetrics(doc->defaultFont(), p.device()).ascent()
1175  + 5 * p.device()->logicalDpiY() / 72);
1176 
1177  doc->setPageSize(body.size());
1178 
1179  int docCopies = printer.numCopies();
1180  for (int copy = 0; copy < docCopies; ++copy) {
1181 
1182  int lastPage = layout->pageCount();
1183  for ( int page = 1; page <= lastPage ; ++page ) {
1184  p.save();
1185  p.translate(body.left(), body.top() - (page - 1) * body.height());
1186  QRectF view(0, (page - 1) * body.height(), body.width(), body.height());
1187 
1188  QAbstractTextDocumentLayout *layout = doc->documentLayout();
1189  QAbstractTextDocumentLayout::PaintContext ctx;
1190 
1191  p.setClipRect(view);
1192  ctx.clip = view;
1193 
1194  // don't use the system palette text as default text color, on HP/UX
1195  // for example that's white, and white text on white paper doesn't
1196  // look that nice
1197  ctx.palette.setColor(QPalette::Text, Qt::black);
1198 
1199  layout->draw(&p, ctx);
1200 
1201  if (!pageNumberPos.isNull()) {
1202  p.setClipping(false);
1203  p.setFont(QFont(doc->defaultFont()));
1204  const QString pageString = QString::number(page);
1205 
1206  p.drawText(qRound(pageNumberPos.x() - p.fontMetrics().width(pageString)),
1207  qRound(pageNumberPos.y() + view.top()),
1208  pageString);
1209  }
1210 
1211  p.restore();
1212 
1213  if ( (page+1) <= lastPage ) {
1214  printer.newPage();
1215  }
1216  }
1217  }
1218  }
1219 
1220 }
1221 
1222 void KJotsWidget::selectNext( int role, int step )
1223 {
1224  QModelIndexList list = treeview->selectionModel()->selectedRows();
1225  Q_ASSERT( list.size() == 1 );
1226 
1227  QModelIndex idx = list.at( 0 );
1228 
1229  const int column = idx.column();
1230 
1231  QModelIndex sibling = idx.sibling( idx.row() + step, column );
1232  while ( sibling.isValid() )
1233  {
1234  if ( sibling.data( role ).toInt() >= 0 )
1235  {
1236  treeview->selectionModel()->select( sibling, QItemSelectionModel::SelectCurrent );
1237  return;
1238  }
1239  sibling = sibling.sibling( sibling.row() + step, column );
1240  }
1241  kWarning() << "No valid selection";
1242 }
1243 
1244 void KJotsWidget::nextBook()
1245 {
1246  return selectNext( EntityTreeModel::CollectionIdRole, 1 );
1247 }
1248 
1249 void KJotsWidget::nextPage()
1250 {
1251  return selectNext( EntityTreeModel::ItemIdRole, 1 );
1252 }
1253 
1254 void KJotsWidget::prevBook()
1255 {
1256  return selectNext( EntityTreeModel::CollectionIdRole, -1 );
1257 }
1258 
1259 void KJotsWidget::prevPage()
1260 {
1261  return selectNext( EntityTreeModel::ItemIdRole, -1 );
1262 }
1263 
1264 bool KJotsWidget::canGo( int role, int step ) const
1265 {
1266  QModelIndexList list = treeview->selectionModel()->selectedRows();
1267  if ( list.size() != 1 )
1268  {
1269  return false;
1270  }
1271 
1272  QModelIndex currentIdx = list.at( 0 );
1273 
1274  const int column = currentIdx.column();
1275 
1276  Q_ASSERT( currentIdx.isValid() );
1277 
1278  QModelIndex sibling = currentIdx.sibling( currentIdx.row() + step, column );
1279 
1280  while ( sibling.isValid() && sibling != currentIdx )
1281  {
1282  if ( sibling.data( role ).toInt() >= 0 )
1283  return true;
1284 
1285  sibling = sibling.sibling( sibling.row() + step, column );
1286  }
1287 
1288  return false;
1289 }
1290 
1291 bool KJotsWidget::canGoNextPage() const
1292 {
1293  return canGo( EntityTreeModel::ItemIdRole, 1 );
1294 }
1295 
1296 bool KJotsWidget::canGoPreviousPage() const
1297 {
1298  return canGo( EntityTreeModel::ItemIdRole, -1 );
1299 }
1300 
1301 bool KJotsWidget::canGoNextBook() const
1302 {
1303  return canGo( EntityTreeModel::CollectionIdRole, 1 );
1304 }
1305 
1306 bool KJotsWidget::canGoPreviousBook() const
1307 {
1308  return canGo( EntityTreeModel::CollectionIdRole, -1 );
1309 }
1310 
1311 void KJotsWidget::selectionChanged( const QItemSelection &selected, const QItemSelection &deselected )
1312 {
1313  Q_UNUSED( selected );
1314 
1315  emit canGoNextBookChanged( canGoPreviousBook() );
1316  emit canGoNextPageChanged( canGoNextPage() );
1317  emit canGoPreviousBookChanged( canGoPreviousBook() );
1318  emit canGoPreviousPageChanged( canGoPreviousPage() );
1319 
1320  if ( deselected.size() == 1 )
1321  {
1322  editor->document()->setProperty( "textCursor", QVariant::fromValue( editor->textCursor() ) );
1323  if ( editor->document()->isModified() )
1324  {
1325  treeview->model()->setData( deselected.indexes().first(), QVariant::fromValue( editor->document() ), KJotsModel::DocumentRole );
1326  }
1327  }
1328 }
1329 
1333 void KJotsWidget::onShowSearch()
1334 {
1335  onUpdateSearch();
1336 
1337  QTextEdit *browserOrEditor = activeEditor();
1338 
1339  if ( browserOrEditor->textCursor().hasSelection() ) {
1340  searchDialog->setHasSelection(true);
1341  long dialogOptions = searchDialog->options();
1342  dialogOptions |= KFind::SelectedText;
1343  searchDialog->setOptions(dialogOptions);
1344  } else {
1345  searchDialog->setHasSelection(false);
1346  }
1347 
1348  searchDialog->setFindHistory(searchHistory);
1349  searchDialog->show();
1350  onUpdateSearch();
1351 }
1352 
1353 
1357 void KJotsWidget::onUpdateSearch()
1358 {
1359  if ( searchDialog->isVisible() ) {
1360  long searchOptions = searchDialog->options();
1361  if ( searchOptions & KFind::SelectedText ) {
1362  searchAllPages->setCheckState( Qt::Unchecked );
1363  searchAllPages->setEnabled( false );
1364  } else {
1365  searchAllPages->setEnabled( true );
1366  }
1367 
1368  if ( searchAllPages->checkState() == Qt::Checked ) {
1369  searchOptions &= ~KFind::SelectedText;
1370  searchDialog->setOptions( searchOptions );
1371  searchDialog->setHasSelection( false );
1372  } else {
1373  if ( activeEditor()->textCursor().hasSelection() ) {
1374  searchDialog->setHasSelection( true );
1375  }
1376  }
1377 
1378  if ( activeEditor()->textCursor().hasSelection() ) {
1379  if ( searchAllPages->checkState() == Qt::Unchecked ) {
1380  searchDialog->setHasSelection( true );
1381  }
1382  } else {
1383  searchOptions &= ~KFind::SelectedText;
1384  searchDialog->setOptions( searchOptions );
1385  searchDialog->setHasSelection( false );
1386  }
1387  }
1388 }
1389 
1393 void KJotsWidget::onStartSearch()
1394 {
1395  QString searchPattern = searchDialog->pattern();
1396  if ( !searchHistory.contains ( searchPattern ) ) {
1397  searchHistory.prepend( searchPattern );
1398  }
1399 
1400  QTextEdit *browserOrEditor = activeEditor();
1401  QTextCursor cursor = browserOrEditor->textCursor();
1402 
1403  long searchOptions = searchDialog->options();
1404  if ( searchOptions & KFind::FromCursor ) {
1405  searchPos = cursor.position();
1406  searchBeginPos = 0;
1407  cursor.movePosition( QTextCursor::End );
1408  searchEndPos = cursor.position();
1409  } else {
1410  if ( searchOptions & KFind::SelectedText ) {
1411  searchBeginPos = cursor.selectionStart();
1412  searchEndPos = cursor.selectionEnd();
1413  } else {
1414  searchBeginPos = 0;
1415  cursor.movePosition( QTextCursor::End );
1416  searchEndPos = cursor.position();
1417  }
1418 
1419  if ( searchOptions & KFind::FindBackwards ) {
1420  searchPos = searchEndPos;
1421  } else {
1422  searchPos = searchBeginPos;
1423  }
1424  }
1425 
1426  m_xmlGuiClient->actionCollection()->action( QLatin1String(KStandardAction::name( KStandardAction::FindNext )) )->setEnabled( true );
1427 
1428  onRepeatSearch();
1429 }
1430 
1434 void KJotsWidget::onRepeatSearch()
1435 {
1436  if ( search( false ) == 0 ) {
1437  KMessageBox::sorry( 0, i18n( "<qt>No matches found.</qt>" ) );
1438  m_xmlGuiClient->actionCollection()->action( QLatin1String(KStandardAction::name( KStandardAction::FindNext )) )->setEnabled( false );
1439  }
1440 }
1441 
1445 void KJotsWidget::onEndSearch()
1446 {
1447  m_xmlGuiClient->actionCollection()->action( QLatin1String(KStandardAction::name( KStandardAction::FindNext )) )->setEnabled( false );
1448 }
1449 
1453 void KJotsWidget::onShowReplace()
1454 {
1455  Q_ASSERT( editor->isVisible() );
1456 
1457  if ( editor->textCursor().hasSelection() ) {
1458  replaceDialog->setHasSelection( true );
1459  long dialogOptions = replaceDialog->options();
1460  dialogOptions |= KFind::SelectedText;
1461  replaceDialog->setOptions( dialogOptions );
1462  } else {
1463  replaceDialog->setHasSelection( false );
1464  }
1465 
1466  replaceDialog->setFindHistory( searchHistory );
1467  replaceDialog->setReplacementHistory( replaceHistory );
1468  replaceDialog->show();
1469  onUpdateReplace();
1470 }
1471 
1475 void KJotsWidget::onUpdateReplace()
1476 {
1477  if ( replaceDialog->isVisible() ) {
1478  long replaceOptions = replaceDialog->options();
1479  if ( replaceOptions & KFind::SelectedText ) {
1480  replaceAllPages->setCheckState( Qt::Unchecked );
1481  replaceAllPages->setEnabled( false );
1482  } else {
1483  replaceAllPages->setEnabled( true );
1484  }
1485 
1486  if ( replaceAllPages->checkState() == Qt::Checked ) {
1487  replaceOptions &= ~KFind::SelectedText;
1488  replaceDialog->setOptions( replaceOptions );
1489  replaceDialog->setHasSelection( false );
1490  } else {
1491  if ( activeEditor()->textCursor().hasSelection() ) {
1492  replaceDialog->setHasSelection( true );
1493  }
1494  }
1495  }
1496 }
1497 
1501 void KJotsWidget::onStartReplace()
1502 {
1503  QString searchPattern = replaceDialog->pattern();
1504  if ( !searchHistory.contains ( searchPattern ) ) {
1505  searchHistory.prepend( searchPattern );
1506  }
1507 
1508  QString replacePattern = replaceDialog->replacement();
1509  if ( !replaceHistory.contains ( replacePattern ) ) {
1510  replaceHistory.prepend( replacePattern );
1511  }
1512 
1513  QTextCursor cursor = editor->textCursor();
1514 
1515  long replaceOptions = replaceDialog->options();
1516  if ( replaceOptions & KFind::FromCursor ) {
1517  replacePos = cursor.position();
1518  replaceBeginPos = 0;
1519  cursor.movePosition( QTextCursor::End );
1520  replaceEndPos = cursor.position();
1521  } else {
1522  if ( replaceOptions & KFind::SelectedText ) {
1523  replaceBeginPos = cursor.selectionStart();
1524  replaceEndPos = cursor.selectionEnd();
1525  } else {
1526  replaceBeginPos = 0;
1527  cursor.movePosition( QTextCursor::End );
1528  replaceEndPos = cursor.position();
1529  }
1530 
1531  if ( replaceOptions & KFind::FindBackwards ) {
1532  replacePos = replaceEndPos;
1533  } else {
1534  replacePos = replaceBeginPos;
1535  }
1536  }
1537 
1538  replaceStartPage = treeview->selectionModel()->selectedRows().first();
1539 
1540  //allow KReplaceDialog to exit so the user can see.
1541  QTimer::singleShot( 0, this, SLOT(onRepeatReplace()) );
1542 }
1543 
1547 void KJotsWidget::onRepeatReplace()
1548 {
1549  KJotsReplaceNextDialog *dlg = 0;
1550 
1551  QString searchPattern = replaceDialog->pattern();
1552  QString replacePattern = replaceDialog->replacement();
1553  int found = 0;
1554  int replaced = 0;
1555 
1556  long replaceOptions = replaceDialog->options();
1557  if ( replaceOptions & KReplaceDialog::PromptOnReplace ) {
1558  dlg = new KJotsReplaceNextDialog( this );
1559  }
1560 
1561  forever {
1562  if ( !search( true ) ) {
1563  break;
1564  }
1565 
1566  QTextCursor cursor = editor->textCursor();
1567  if ( !cursor.hasSelection() ) {
1568  break;
1569  } else {
1570  ++found;
1571  }
1572 
1573  QString replacementText = replacePattern;
1574  if ( replaceOptions & KReplaceDialog::BackReference ) {
1575  QRegExp regExp ( searchPattern, ( replaceOptions & Qt::CaseSensitive ) ?
1576  Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::RegExp2 );
1577  regExp.indexIn(cursor.selectedText());
1578  int capCount = regExp.numCaptures();
1579  for ( int i=0; i <= capCount; ++i ) {
1580  QString c = QString::fromLatin1( "\\%1" ).arg( i );
1581  replacementText.replace( c, regExp.cap( i ) );
1582  }
1583  }
1584 
1585  if ( replaceOptions & KReplaceDialog::PromptOnReplace ) {
1586  dlg->setLabel( cursor.selectedText(), replacementText );
1587 
1588  if ( !dlg->exec() ) {
1589  break;
1590  }
1591 
1592  if ( dlg->answer() != KDialog::User2 ) {
1593  cursor.insertText( replacementText );
1594  editor->setTextCursor( cursor );
1595  ++replaced;
1596  }
1597 
1598  if ( dlg->answer() == KDialog::User1 ) {
1599  replaceOptions |= ~KReplaceDialog::PromptOnReplace;
1600  }
1601  } else {
1602  cursor.insertText( replacementText );
1603  editor->setTextCursor( cursor );
1604  ++replaced;
1605  }
1606  }
1607 
1608  if ( replaced == found )
1609  {
1610  KMessageBox::information( 0, i18np( "<qt>Replaced 1 occurrence.</qt>", "<qt>Replaced %1 occurrences.</qt>", replaced ) );
1611  }
1612  else if ( replaced < found )
1613  {
1614  KMessageBox::information( 0,
1615  i18np( "<qt>Replaced %2 of 1 occurrence.</qt>", "<qt>Replaced %2 of %1 occurrences.</qt>", found, replaced ) );
1616  }
1617 
1618  if ( dlg ) {
1619  delete dlg;
1620  }
1621 }
1622 
1626 void KJotsWidget::onEndReplace()
1627 {
1628 }
1629 
1634 int KJotsWidget::search( bool replacing )
1635 {
1636  int rc = 0;
1637  int *beginPos = replacing ? &replaceBeginPos : &searchBeginPos;
1638  int *endPos = replacing ? &replaceEndPos : &searchEndPos;
1639  long options = replacing ? replaceDialog->options() : searchDialog->options();
1640  QString pattern = replacing ? replaceDialog->pattern() : searchDialog->pattern();
1641  int *curPos = replacing ? &replacePos : &searchPos;
1642 
1643  QModelIndex startPage = replacing ? replaceStartPage : treeview->selectionModel()->selectedRows().first();
1644 
1645  bool allPages = false;
1646  QCheckBox *box = replacing ? replaceAllPages : searchAllPages;
1647  if ( box->isEnabled() && box->checkState() == Qt::Checked ) {
1648  allPages = true;
1649  }
1650 
1651  QTextDocument::FindFlags findFlags = 0;
1652  if ( options & Qt::CaseSensitive ) {
1653  findFlags |= QTextDocument::FindCaseSensitively;
1654  }
1655 
1656  if ( options & KFind::WholeWordsOnly ) {
1657  findFlags |= QTextDocument::FindWholeWords;
1658  }
1659 
1660  if ( options & KFind::FindBackwards ) {
1661  findFlags |= QTextDocument::FindBackward;
1662  }
1663 
1664  // We will find a match or return 0
1665  int attempts = 0;
1666  forever {
1667  ++attempts;
1668 
1669  QTextEdit *browserOrEditor = activeEditor();
1670  QTextDocument *theDoc = browserOrEditor->document();
1671 
1672  QTextCursor cursor;
1673  if ( options & KFind::RegularExpression ) {
1674  QRegExp regExp ( pattern, ( options & Qt::CaseSensitive ) ?
1675  Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::RegExp2 );
1676  cursor = theDoc->find( regExp, *curPos, findFlags );
1677  } else {
1678  cursor = theDoc->find( pattern, *curPos, findFlags );
1679  }
1680 
1681  if ( cursor.hasSelection() ) {
1682  if ( cursor.selectionStart() >= *beginPos && cursor.selectionEnd() <= *endPos ) {
1683  browserOrEditor->setTextCursor( cursor );
1684  browserOrEditor->ensureCursorVisible();
1685  *curPos = ( options & KFind::FindBackwards ) ?
1686  cursor.selectionStart() : cursor.selectionEnd();
1687  rc = 1;
1688  break;
1689  }
1690  }
1691 
1692  //No match. Determine what to do next.
1693 
1694  if ( replacing && !( options & KFind::FromCursor ) && !allPages ) {
1695  break;
1696  }
1697 
1698  if ( ( options & KFind::FromCursor ) && !allPages ) {
1699  if ( KMessageBox::questionYesNo( this,
1700  i18n("<qt>End of search area reached. Do you want to wrap around and continue?</qt>")) ==
1701  KMessageBox::No ) {
1702  rc = 3;
1703  break;
1704  }
1705  }
1706 
1707  if ( allPages ) {
1708  if ( options & KFind::FindBackwards ) {
1709  if ( canGoPreviousPage() )
1710  prevPage();
1711  } else {
1712  if ( canGoNextPage() )
1713  nextPage();
1714  }
1715 
1716  if ( startPage == treeview->selectionModel()->selectedRows().first() ) {
1717  rc = 0;
1718  break;
1719  }
1720 
1721  *beginPos = 0;
1722  cursor = editor->textCursor();
1723  cursor.movePosition( QTextCursor::End );
1724  *endPos = cursor.position();
1725  *curPos = ( options & KFind::FindBackwards ) ? *endPos : *beginPos;
1726  continue;
1727  }
1728 
1729  // By now, we should have figured out what to do. In all remaining cases we
1730  // will automatically loop and try to "find next" from the top/bottom, because
1731  // I like this behavior the best.
1732  if ( attempts <= 1 ) {
1733  *curPos = ( options & KFind::FindBackwards ) ? *endPos : *beginPos;
1734  } else {
1735  // We've already tried the loop and failed to find anything. Bail.
1736  rc = 0;
1737  break;
1738  }
1739  }
1740 
1741  return rc;
1742 }
1743 
1744 
1745 void KJotsWidget::updateCaption()
1746 {
1747  emit captionChanged( treeview->captionForSelection( QLatin1String(" / ") ) );
1748 }
1749 
1750 void KJotsWidget::dataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight )
1751 {
1752  QModelIndexList rows = treeview->selectionModel()->selectedRows();
1753 
1754  if ( rows.size() != 1 )
1755  return;
1756 
1757  QItemSelection changed( topLeft, bottomRight );
1758  if ( changed.contains( rows.first() ) )
1759  {
1760  emit captionChanged( treeview->captionForSelection( QLatin1String(" / ") ) );
1761  }
1762 }
1763 
1764 bool KJotsWidget::queryClose()
1765 {
1766  KJotsSettings::setSplitterSizes(m_splitter->sizes());
1767 
1768  KJotsSettings::self()->writeConfig();
1769  m_orderProxy->saveOrder();
1770 
1771  return true;
1772 }
1773 
1774 void KJotsWidget::actionLock()
1775 {
1776  QModelIndexList selection = treeview->selectionModel()->selectedRows();
1777 
1778  if ( selection.isEmpty() )
1779  return;
1780 
1781  Collection::List collections;
1782  Item::List items;
1783  foreach ( const QModelIndex &idx, selection )
1784  {
1785  Collection col = idx.data( EntityTreeModel::CollectionRole ).value<Collection>();
1786  if ( col.isValid() )
1787  {
1788  collections << col;
1789  } else {
1790  Item item = idx.data( EntityTreeModel::ItemRole ).value<Item>();
1791  if ( item.isValid() )
1792  items << item;
1793  }
1794  }
1795  if ( collections.isEmpty() && items.isEmpty() )
1796  return;
1797 
1798  KJotsLockJob *job = new KJotsLockJob(collections, items, this);
1799 }
1800 
1801 void KJotsWidget::actionUnlock()
1802 {
1803  QModelIndexList selection = treeview->selectionModel()->selectedRows();
1804 
1805  if ( selection.isEmpty() )
1806  return;
1807 
1808  Collection::List collections;
1809  Item::List items;
1810  foreach ( const QModelIndex &idx, selection )
1811  {
1812  Collection col = idx.data( EntityTreeModel::CollectionRole ).value<Collection>();
1813  if ( col.isValid() )
1814  {
1815  collections << col;
1816  } else {
1817  Item item = idx.data( EntityTreeModel::ItemRole ).value<Item>();
1818  if ( item.isValid() )
1819  items << item;
1820  }
1821  }
1822  if ( collections.isEmpty() && items.isEmpty() )
1823  return;
1824 
1825  KJotsLockJob *job = new KJotsLockJob(collections, items, KJotsLockJob::UnlockJob, this);
1826 }
1827 
1828 void KJotsWidget::actionSortChildrenAlpha()
1829 {
1830  QModelIndexList selection = treeview->selectionModel()->selectedRows();
1831 
1832  foreach( const QModelIndex &index, selection )
1833  {
1834  const QPersistentModelIndex persistent( index );
1835  m_sortProxyModel->sortChildrenAlphabetically( m_orderProxy->mapToSource( index ) );
1836  m_orderProxy->clearOrder( persistent );
1837  }
1838 }
1839 
1840 void KJotsWidget::actionSortChildrenByDate()
1841 {
1842  QModelIndexList selection = treeview->selectionModel()->selectedRows();
1843 
1844  foreach( const QModelIndex &index, selection )
1845  {
1846  const QPersistentModelIndex persistent( index );
1847  m_sortProxyModel->sortChildrenByCreationTime( m_orderProxy->mapToSource( index ) );
1848  m_orderProxy->clearOrder( persistent );
1849  }
1850 }
1851 
QWidget::layout
QLayout * layout() const
QTextCursor::position
int position() const
QTimer::setInterval
void setInterval(int msec)
QItemSelection::indexes
QModelIndexList indexes() const
QVariant::toLongLong
qlonglong toLongLong(bool *ok) const
KJotsConfigDlg
Definition: kjotsconfigdlg.h:55
QModelIndex
QPrinter::numCopies
int numCopies() const
KJotsWidget::changeTheme
void changeTheme()
Definition: kjotswidget.cpp:1019
kjotssortproxymodel.h
QWidget
QTextDocument::pageSize
pageSize
KJotsWidget::canGoPreviousBook
bool canGoPreviousBook() const
Definition: kjotswidget.cpp:1306
QHash::insert
iterator insert(const Key &key, const T &value)
kjotsconfigdlg.h
KJotsWidget::canGoPreviousPage
bool canGoPreviousPage() const
Definition: kjotswidget.cpp:1296
KJotsWidget::canGoNextBookChanged
void canGoNextBookChanged(bool)
KJotsWidget::KJotsWidget
KJotsWidget(QWidget *parent, KXMLGUIClient *xmlGuiclient, Qt::WindowFlags f=0)
Definition: kjotswidget.cpp:113
QTextCursor
KJotsWidget::canGoNextBook
bool canGoNextBook() const
Definition: kjotswidget.cpp:1301
QSplitter::setSizes
void setSizes(const QList< int > &list)
QWidget::cursor
QCursor cursor() const
KJotsTreeView
Definition: kjotstreeview.h:29
QGridLayout::addWidget
void addWidget(QWidget *widget, int row, int column, QFlags< Qt::AlignmentFlag > alignment)
QRectF::x
qreal x() const
QRectF::y
qreal y() const
QSplitter::setStretchFactor
void setStretchFactor(int index, int stretch)
QSortFilterProxyModel::setSourceModel
virtual void setSourceModel(QAbstractItemModel *sourceModel)
QPrinter
QTextCharFormat::anchorHref
QString anchorHref() const
QTextFrame::setFrameFormat
void setFrameFormat(const QTextFrameFormat &format)
KJotsEntity
A wrapper QObject making some book and page properties available to Grantlee.
Definition: kjotsmodel.h:39
KJotsReplaceNextDialog::answer
int answer() const
Definition: kjotsreplacenextdialog.h:37
QTextCursor::selectionStart
int selectionStart() const
KJotsWidget::exportSelectionToHtml
void exportSelectionToHtml()
Definition: kjotswidget.cpp:1027
QTextEdit::setHtml
void setHtml(const QString &text)
QFont
QRectF::size
QSizeF size() const
QTextCursor::selectedText
QString selectedText() const
QPointer
QDBusConnection::registerObject
bool registerObject(const QString &path, QObject *object, QFlags< QDBusConnection::RegisterOption > options)
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QWidget::isVisible
bool isVisible() const
KJotsWidget::deletePage
void deletePage()
Definition: kjotswidget.cpp:735
QHBoxLayout
KJotsWidget::queryClose
Q_SCRIPTABLE bool queryClose()
Definition: kjotswidget.cpp:1764
QVariant::value
T value() const
QRectF::top
qreal top() const
QDBusConnection::sessionBus
QDBusConnection sessionBus()
QGridLayout
QFontMetrics
QTextFrameFormat
QSet::insert
const_iterator insert(const T &value)
QAbstractTextDocumentLayout
QAbstractPrintDialog::PrintDialogOptions
typedef PrintDialogOptions
KJotsWidget::exportSelectionToPlainText
void exportSelectionToPlainText()
Definition: kjotswidget.cpp:1053
KJotsWidget::exportSelectionToXml
void exportSelectionToXml()
Definition: kjotswidget.cpp:1075
KJotsWidget::updateCaption
void updateCaption()
Definition: kjotswidget.cpp:1745
QAbstractPrintDialog
QObject::tr
QString tr(const char *sourceText, const char *disambiguation, int n)
QRectF::left
qreal left() const
KJotsEdit
Definition: kjotsedit.h:35
QFile
KJotsWidget::renderSelection
void renderSelection()
Definition: kjotswidget.cpp:969
QTextCursor::movePosition
bool movePosition(MoveOperation operation, MoveMode mode, int n)
QTextEdit::copy
void copy()
KJotsWidget::getThemeFromUser
QString getThemeFromUser()
Definition: kjotswidget.cpp:1001
QList::size
int size() const
QPointF
kjotstreeview.h
localresourcecreator.h
KJotsWidget::selectNext
void selectNext(int role, int step)
Definition: kjotswidget.cpp:1222
KJotsWidget::canGoNextPage
bool canGoNextPage() const
Definition: kjotswidget.cpp:1291
KJotsTreeView::captionForSelection
QString captionForSelection(const QString &sep) const
Definition: kjotstreeview.cpp:105
QRegExp
QObject::name
const char * name() const
QTextDocument::find
QTextCursor find(const QString &subString, int position, QFlags< QTextDocument::FindFlag > options) const
QModelIndex::isValid
bool isValid() const
KJotsWidget::newBook
Q_SCRIPTABLE void newBook()
Definition: kjotswidget.cpp:797
QTextCursor::hasSelection
bool hasSelection() const
QWidget::setEnabled
void setEnabled(bool)
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QString::number
QString number(int n, int base)
KJotsWidget::doCreateNewPage
void doCreateNewPage(const Akonadi::Collection &collection)
Definition: kjotswidget.cpp:847
KJotsWidget::activeAnchorChanged
void activeAnchorChanged(const QString &anchorTarget, const QString &anchorText)
Signals that the text cursor in the editor is now on a different anchor, or not on an anchor anymore...
KJotsSortProxyModel
Definition: kjotssortproxymodel.h:29
QStackedWidget::setCurrentWidget
void setCurrentWidget(QWidget *widget)
QSplitter::sizes
QList< int > sizes() const
QObject::property
QVariant property(const char *name) const
QWidget::topLevelWidget
QWidget * topLevelWidget() const
QTimer
QVariant::toInt
int toInt(bool *ok) const
KJotsWidget::captionChanged
void captionChanged(const QString &newCaption)
QPrinter::setCreator
void setCreator(const QString &creator)
QHash
QPrintDialog
QTextDocument::rootFrame
QTextFrame * rootFrame() const
QObject
QWidget::setFocus
void setFocus()
QCheckBox
QTextCursor::insertText
void insertText(const QString &text)
QPainter
KJotsEntity::setIndex
void setIndex(const QModelIndex &index)
Definition: kjotsmodel.cpp:50
QObject::objectName
objectName
QString::isEmpty
bool isEmpty() const
QModelIndex::row
int row() const
kjotswidget.h
KJotsWidget::renderSelectionToHtml
QString renderSelectionToHtml()
Definition: kjotswidget.cpp:875
QTextCursor::isNull
bool isNull() const
KJotsBookmarks
Definition: kjotsbookmarks.h:31
QTextDocument::documentLayout
QAbstractTextDocumentLayout * documentLayout() const
QPrinter::setDocName
void setDocName(const QString &name)
KJotsWidget::newPage
Q_SCRIPTABLE void newPage()
Definition: kjotswidget.cpp:825
KJotsReplaceNextDialog::setLabel
void setLabel(const QString &pattern, const QString &replacement)
Definition: kjotsreplacenextdialog.cpp:47
QStackedWidget
QSplitter::setOpaqueResize
void setOpaqueResize(bool opaque)
KJotsWidget::canGoPreviousPageChanged
void canGoPreviousPageChanged(bool)
KJotsBrowser
Definition: kjotsbrowser.h:30
QString
QList
QPrinter::printRange
PrintRange printRange() const
QLayout::setMargin
void setMargin(int margin)
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QTextEdit::setTextCursor
void setTextCursor(const QTextCursor &cursor)
KJotsWidget::prevPage
void prevPage()
Definition: kjotswidget.cpp:1259
QAbstractTextDocumentLayout::PaintContext
QStringList
QInputDialog::getText
QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode, const QString &text, bool *ok, QFlags< Qt::WindowType > flags, QFlags< Qt::InputMethodHint > inputMethodHints)
KJotsLockJob
Definition: kjotslockjob.h:29
QTextCharFormat
QTextDocument::defaultFont
defaultFont
QTextEdit::document
QTextDocument * document() const
kjotsedit.h
kjotsbookmarks.h
QRectF::isNull
bool isNull() const
kjotsbrowser.h
QPrinter::setFullPage
void setFullPage(bool fp)
QTimer::stop
void stop()
QVariant::fromValue
QVariant fromValue(const T &value)
KJotsModel
Definition: kjotsmodel.h:74
QFile::close
virtual void close()
KJotsWidget::updateMenu
void updateMenu()
Definition: kjotswidget.cpp:603
KJotsEdit::delayedInitialization
void delayedInitialization(KActionCollection *)
Definition: kjotsedit.cpp:110
KJotsWidget::canGoPreviousBookChanged
void canGoPreviousBookChanged(bool)
KJotsWidget::printSelection
void printSelection()
Definition: kjotswidget.cpp:1108
QPrinter::newPage
bool newPage()
KJotsWidget::activeEditor
QTextEdit * activeEditor()
Definition: kjotswidget.cpp:595
QItemSelection
KJotsModel::DocumentRole
Definition: kjotsmodel.h:84
QString::replace
QString & replace(int position, int n, QChar after)
QTextEdit::ensureCursorVisible
void ensureCursorVisible()
QSplitter
QPersistentModelIndex
KJotsSortProxyModel::sortChildrenAlphabetically
void sortChildrenAlphabetically(const QModelIndex &parent)
Definition: kjotssortproxymodel.cpp:71
QRectF::width
qreal width() const
KJotsWidget::canGoNextPageChanged
void canGoNextPageChanged(bool)
KJotsSortProxyModel::sortChildrenByCreationTime
void sortChildrenByCreationTime(const QModelIndex &parent)
Definition: kjotssortproxymodel.cpp:82
KJotsWidget::nextBook
void nextBook()
Definition: kjotswidget.cpp:1244
QModelIndex::data
QVariant data(int role) const
kjotslockjob.h
KJotsWidget::deleteBook
void deleteBook()
Definition: kjotswidget.cpp:765
QLatin1String
QKeySequence
QTextDocument
QRectF
QModelIndex::sibling
QModelIndex sibling(int row, int column) const
KJotsWidget::~KJotsWidget
~KJotsWidget()
Definition: kjotswidget.cpp:413
KJotsWidget::deleteMultiple
void deleteMultiple()
Definition: kjotswidget.cpp:708
KJotsWidget::nextPage
void nextPage()
Definition: kjotswidget.cpp:1249
KJotsBrowser::delayedInitialization
void delayedInitialization()
Definition: kjotsbrowser.cpp:43
KJotsReplaceNextDialog
Definition: kjotsreplacenextdialog.h:31
QAction
KJotsWidget::prevBook
void prevBook()
Definition: kjotswidget.cpp:1254
QAbstractTextDocumentLayout::pageCount
virtual int pageCount() const =0
KJotsLockJob::UnlockJob
Definition: kjotslockjob.h:36
QModelIndex::column
int column() const
QTextDocument::setHtml
void setHtml(const QString &html)
QIODevice::write
qint64 write(const char *data, qint64 maxSize)
kjotsmodel.h
QString::fromLatin1
QString fromLatin1(const char *str, int size)
KJotsWidget::printPreviewSelection
void printPreviewSelection()
Definition: kjotswidget.cpp:1097
QTimer::start
void start(int msec)
QRectF::height
qreal height() const
KJotsModel::GrantleeObjectRole
Definition: kjotsmodel.h:83
Qt::WindowFlags
typedef WindowFlags
QList::prepend
void prepend(const T &value)
QAbstractTextDocumentLayout::setPaintDevice
void setPaintDevice(QPaintDevice *device)
QTextFrame::frameFormat
QTextFrameFormat frameFormat() const
KJotsWidget::renderSelectionToPlainText
QString renderSelectionToPlainText()
Definition: kjotswidget.cpp:906
QTextCursor::selectionEnd
int selectionEnd() const
QStackedWidget::addWidget
int addWidget(QWidget *widget)
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QCheckBox::checkState
Qt::CheckState checkState() const
kjotsreplacenextdialog.h
KJotsWidget::migrateNoteData
void migrateNoteData(const QString &migrator, const QString &type=QString())
Definition: kjotswidget.cpp:556
QTextEdit
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QVariant::toString
QString toString() const
QTextFrameFormat::setMargin
void setMargin(qreal margin)
QAction::setEnabled
void setEnabled(bool)
QTextEdit::textCursor
QTextCursor textCursor() const
KJotsTreeView::delayedInitialization
void delayedInitialization()
Definition: kjotstreeview.cpp:95
QCheckBox::setCheckState
void setCheckState(Qt::CheckState state)
QTextDocument::FindFlags
typedef FindFlags
KJotsWidget::search
int search(bool)
Definition: kjotswidget.cpp:1634
QTimer::singleShot
singleShot
KJotsWidget::renderSelectionToXml
QString renderSelectionToXml()
Definition: kjotswidget.cpp:938
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