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