summaryrefslogtreecommitdiffstats
path: root/kjots
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit2bda8f7717adf28da4af0d34fb82f63d2868c31d (patch)
tree8d927b7b47a90c4adb646482a52613f58acd6f8c /kjots
downloadtdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.tar.gz
tdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeutils@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kjots')
-rw-r--r--kjots/ANNOUNCE26
-rw-r--r--kjots/BUGS6
-rw-r--r--kjots/CHANGES75
-rw-r--r--kjots/KJotsMain.cpp1199
-rw-r--r--kjots/KJotsMain.h165
-rw-r--r--kjots/KJotsSettings.kcfgc8
-rw-r--r--kjots/Kjots.desktop80
-rw-r--r--kjots/Makefile.am28
-rw-r--r--kjots/README33
-rw-r--r--kjots/confpagefont.ui38
-rw-r--r--kjots/confpagemisc.ui152
-rw-r--r--kjots/icons/Makefile.am6
-rw-r--r--kjots/icons/README24
-rw-r--r--kjots/icons/filedel.pngbin0 -> 892 bytes
-rw-r--r--kjots/icons/hi16-app-kjots.pngbin0 -> 902 bytes
-rw-r--r--kjots/icons/hi22-app-kjots.pngbin0 -> 1318 bytes
-rw-r--r--kjots/icons/hi32-app-kjots.pngbin0 -> 2287 bytes
-rw-r--r--kjots/icons/hi48-app-kjots.pngbin0 -> 3755 bytes
-rw-r--r--kjots/icons/hi64-app-kjots.pngbin0 -> 5426 bytes
-rw-r--r--kjots/kjots.kcfg35
-rw-r--r--kjots/kjotsbookmarks.cpp51
-rw-r--r--kjots/kjotsbookmarks.h51
-rw-r--r--kjots/kjotsedit.cpp150
-rw-r--r--kjots/kjotsedit.h54
-rw-r--r--kjots/kjotsentry.cpp1234
-rw-r--r--kjots/kjotsentry.h179
-rw-r--r--kjots/kjotsui.rc41
-rw-r--r--kjots/main.cpp98
28 files changed, 3733 insertions, 0 deletions
diff --git a/kjots/ANNOUNCE b/kjots/ANNOUNCE
new file mode 100644
index 0000000..d9a696f
--- /dev/null
+++ b/kjots/ANNOUNCE
@@ -0,0 +1,26 @@
+kjots (version 0.3.0) - a note taker
+------------------------------------
+
+Hi !
+
+New versions of kjots go directly into the kdeutils distribution.
+This is for version 0.3.0.
+
+What is kjots
+-------------
+
+Name and idea for this program are taken from the jots program included
+in the tkgoodstuff package by Mark Crimmins ([email protected]).
+
+Kjots helps you to write down some notes and maybe reduces the stack of
+paper lying on your desk.
+
+New in this version
+-------------------
+
+- added lots of keyboard shortcuts
+
+
+Regards.
+
+ Chris.
diff --git a/kjots/BUGS b/kjots/BUGS
new file mode 100644
index 0000000..f8de6a4
--- /dev/null
+++ b/kjots/BUGS
@@ -0,0 +1,6 @@
+kjots - a note taker
+------------------------------------
+
+Please use the bug tracking system at http://bugs.kde.org to
+report bugs.
+
diff --git a/kjots/CHANGES b/kjots/CHANGES
new file mode 100644
index 0000000..9815d90
--- /dev/null
+++ b/kjots/CHANGES
@@ -0,0 +1,75 @@
+
+new in version 0.5 (Aaron J. Seigo)
+- redesign of UI
+- use of XMLGUI
+- simplification of internals
+- insertion of date and time
+- printing
+- stability improvements
+- made KUniqueApp
+
+(Carsten Pfeiffer <[email protected]>)
+- use KEdit instead of QMultiLineEdit directly
+ -> gains Search & replace + undo
+- allocate KTMainWindow on the heap to avoid double deletion on quit
+
+new in version 0.4 (Mario Weilguni <[email protected]>)
+- works now with Qt 2.0
+- fixed broken layout of main window
+- layout improvements in AskFileName()
+- layout improvements in SubjList()
+- compiles without warnings
+- "Apply" button is only activated when changes were made
+- improved layout of configuration dialog
+- fixed a bug in the font selection
+
+- now compiles with EGCS ( Robert Williams )
+
+new in version 0.3.0
+- added lots of keyboard shortcuts
+- added klocale->translate()
+
+new in version 0.2.6
+- icons should be visible in the toolbar
+
+new in version 0.2.5
+- you may save books and pages to an ascii file
+- more kde conforming due to the use of KTopLevelWidget
+
+new in version 0.2.4
+- uses kfontdialog to set the font of the editor widget
+- you may select an URL in your text and press the right mouse button
+ to execute a program with this URL. The program to execute is
+ configurable for http and ftp URLs.
+- some code cleanup
+
+new in version 0.2.3
+- compiles with libkde-970510 NOTE: this version is needed !
+- shouldn't segfault, if you delete pages
+- double clicking on an entry in the subjectlist closes the subjectlist window
+- fixed fonds -> fonts ;)
+
+new in version 0.2.2
+- compiles with libkde-0.7.2
+- several bug fixes
+
+new in version 0.2.1
+
+- should compile cleanly with libqt1.2 and libkde-0.7.1 and later
+
+new in version 0.2.0
+
+- changed the layout to be more KDE conforming (toolbar, statusbar,...)
+- folders are now called books and entries are pages
+- added subject to each page
+- you may popup a window with a list of all subjects and use it to find
+ pages more easily
+- further reduced the minimum size of the window
+
+new in version 0.1.1
+
+- does not delete empty lines anymore
+- you may insert TABs into your text
+- the minimum size of the window is smaller now
+- the size of the window is saved and read the next
+ time kjots is started
diff --git a/kjots/KJotsMain.cpp b/kjots/KJotsMain.cpp
new file mode 100644
index 0000000..a54cead
--- /dev/null
+++ b/kjots/KJotsMain.cpp
@@ -0,0 +1,1199 @@
+//
+// kjots
+//
+// Copyright (C) 1997 Christoph Neerfeld
+// Copyright (C) 2002-2004 Aaron J. Seigo
+// Copyright (C) 2003 Stanislav Kljuhhin
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+#include <qheader.h>
+#include <qwidgetstack.h>
+
+#include <kio/netaccess.h>
+
+#include <kaction.h>
+#include <kapplication.h>
+#include <kbookmarkmenu.h>
+#include <kconfigdialog.h>
+#include <kdebug.h>
+#include <keditcl.h>
+#include <kencodingfiledialog.h>
+#include <kglobalsettings.h>
+#include <kinputdialog.h>
+#include <kmessagebox.h>
+#include <kpopupmenu.h>
+#include <krun.h>
+#include <kstandarddirs.h>
+#include <kstdaccel.h>
+#include <ktextbrowser.h>
+
+#include "KJotsMain.h"
+#include "KJotsSettings.h"
+#include "kjotsbookmarks.h"
+#include "kjotsedit.h"
+#include "kjotsentry.h"
+#include "confpagemisc.h"
+#include "confpagefont.h"
+
+#define KJOTSVERSION "0.7"
+
+extern KIconLoader* global_pix_loader;
+
+//----------------------------------------------------------------------
+// KJOTSMAIN
+//----------------------------------------------------------------------
+KJotsMain::KJotsMain(const char* name)
+ : KMainWindow(0,name),
+ currentEntry(0),
+ invalidMoveFlag(false)
+{
+ //
+ // Main widget
+ //
+ QWidget* f_main = new QFrame( this, "Frame_0" );
+ setCentralWidget(f_main);
+
+ splitter = new QSplitter(f_main);
+ splitter->setOpaqueResize( KGlobalSettings::opaqueResize() );
+
+ // the subject list
+ subjectList = new KListView(splitter, "subjectList");
+ subjectList->setRootIsDecorated(true);
+ subjectList->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding));
+ subjectList->setMinimumWidth(subjectList->fontMetrics().maxWidth() * 10 + 5);
+ subjectList->addColumn(i18n("Pages"));
+ subjectList->setFullWidth(true);
+ subjectList->setHScrollBarMode(QScrollView::AlwaysOff);
+ subjectList->setDefaultRenameAction(QListView::Accept);
+ subjectList->setSorting(-1);
+ subjectList->setAlternateBackground(QColor());
+ subjectList->header()->hide();
+ subjectList->setDragEnabled(true);
+ subjectList->setAcceptDrops(true);
+ subjectList->setItemsMovable(true);
+ subjectList->setItemsRenameable(true);
+ subjectList->setRenameable(0,true);
+
+ textStack = new QWidgetStack(splitter);
+
+ me_text = new KJotsEdit(textStack, "me_text");
+ me_text->setFocusPolicy(QWidget::StrongFocus);
+ me_text->setEnabled(false);
+ textStack->addWidget(me_text);
+ connect(me_text, SIGNAL(findSuccessful()), this, SLOT(slotFindSuccessful()));
+
+ roTextView = new KTextBrowser(textStack, "roTextView", true);
+ textStack->addWidget(roTextView);
+
+ QVBoxLayout *bookGrid = new QVBoxLayout(f_main, KDialog::marginHint(), KDialog::spacingHint());
+ bookGrid->addWidget(splitter, 0, 0);
+ bookGrid->setMargin(0);
+ splitter->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, 2, 1));
+
+ // create actions
+ actions[ACTION_NEXT_BOOK] = new KAction(i18n("Next Book"), QString::null, CTRL + Key_D, this,
+ SLOT(nextBook()), actionCollection(), "go_next_book");
+ actions[ACTION_PREV_BOOK] = new KAction(i18n("Previous Book"), QString::null, CTRL + SHIFT + Key_D, this,
+ SLOT(prevBook()), actionCollection(), "go_prev_book");
+ actions[ACTION_NEXT_PAGE] = new KAction(i18n("Next Page"), QString::null, CTRL + Key_PageDown, this,
+ SLOT(nextPage()), actionCollection(), "go_next_page");
+ actions[ACTION_PREV_PAGE] = new KAction(i18n("Previous Page"), QString::null, CTRL + Key_PageUp, this,
+ SLOT(prevPage()), actionCollection(), "go_prev_page");
+
+ actions[ACTION_NEW_PAGE] = KStdAction::openNew(this, SLOT(newEntry()), actionCollection());
+ actions[ACTION_NEW_PAGE]->setText(i18n("&New Page"));
+ actions[ACTION_NEW_BOOK] = new KAction(i18n("New &Book..."), "contents", CTRL + SHIFT + Key_N, this,
+ SLOT(createNewBook()), actionCollection(), "new_book");
+
+ exportPageMenu = new KActionMenu(i18n("Export Page"), actionCollection(), "save_page_to");
+ actions[ACTION_PAGE2TEXT] = new KAction(i18n("To Text File..."), QString::null, 0, this,
+ SLOT(writePage()), actionCollection(), "save_page_to_ascii");
+ actions[ACTION_PAGE2TEXT]->plug(exportPageMenu->popupMenu());
+ actions[ACTION_PAGE2HTML] = new KAction(i18n("To HTML File..."), QString::null, 0, this,
+ SLOT(writePageToHTML()), actionCollection(), "save_page_to_html");
+ actions[ACTION_PAGE2HTML]->plug(exportPageMenu->popupMenu());
+
+ exportBookMenu = new KActionMenu(i18n("Export Book"), actionCollection(), "save_book_to");
+ actions[ACTION_BOOK2TEXT] = new KAction(i18n("To Text File..."), QString::null, 0, this,
+ SLOT(writeBook()), actionCollection(), "save_book_to_ascii");
+ actions[ACTION_BOOK2TEXT]->plug(exportBookMenu->popupMenu());
+ actions[ACTION_BOOK2HTML] = new KAction(i18n("To HTML File..."), QString::null, 0, this,
+ SLOT(writeBookToHTML()), actionCollection(), "save_book_to_html");
+ actions[ACTION_BOOK2HTML]->plug(exportBookMenu->popupMenu());
+
+ actions[ACTION_DELETE_PAGE] = new KAction(i18n("&Delete Page"), "editdelete", CTRL + Key_Delete, this,
+ SLOT(deleteEntry()), actionCollection(), "del_page");
+ actions[ACTION_DELETE_BOOK] = new KAction(i18n("Delete Boo&k"), "editdelete", CTRL + SHIFT + Key_Delete, this,
+ SLOT(deleteBook()), actionCollection(), "del_folder");
+
+ actions[ACTION_MANUAL_SAVE] = new KAction(i18n("Manual Save"), 0, KStdAccel::save(),
+ this, SLOT(autoSave()), actionCollection(), "manual_save");
+ actions[ACTION_PRINT] = KStdAction::print(this, SLOT(slotPrint()), actionCollection());
+ actions[ACTION_QUIT] = KStdAction::quit(this, SLOT(slotQuit()), actionCollection());
+
+ actions[ACTION_CUT] = KStdAction::cut(me_text, SLOT(cut()), actionCollection());
+ connect(me_text, SIGNAL(copyAvailable(bool)), actions[ACTION_CUT], SLOT(setEnabled(bool)));
+ actions[ACTION_CUT]->setEnabled(false);
+ actions[ACTION_COPY] = KStdAction::copy(me_text, SLOT(copy()), actionCollection());
+ connect(me_text, SIGNAL(copyAvailable(bool)), actions[ACTION_COPY], SLOT(setEnabled(bool)));
+ actions[ACTION_COPY]->setEnabled(false);
+ actions[ACTION_PASTE2TITLE] = new KAction(i18n("Copy &into Page Title"), "editcopy", CTRL+Key_T, this,
+ SLOT(copySelection()), actionCollection(), "copyIntoTitle");
+ connect(me_text, SIGNAL(copyAvailable(bool)), actions[ACTION_PASTE2TITLE], SLOT(setEnabled(bool)));
+ actions[ACTION_PASTE2TITLE]->setEnabled(false);
+ actions[ACTION_PASTE] = KStdAction::pasteText(me_text, SLOT(paste()), actionCollection());
+
+ actions[ACTION_FIND] = KStdAction::find( this, SLOT( slotSearch() ), actionCollection() );
+ actions[ACTION_FIND_NEXT] = KStdAction::findNext( this, SLOT( slotRepeatSearch() ), actionCollection() );
+ actions[ACTION_FIND_NEXT]->setEnabled(false);
+ actions[ACTION_REPLACE] = KStdAction::replace( this, SLOT( slotReplace() ), actionCollection() );
+
+ actions[ACTION_RENAME] = new KAction(i18n("Rename..."), QString::null, CTRL + Key_M, this,
+ SLOT(slotRenameEntry()), actionCollection(), "rename_entry");
+ actions[ACTION_INSERT_DATE] = new KAction(i18n("Insert Date"), "date", CTRL + Key_I, this,
+ SLOT(insertDate()), actionCollection(), "insert_date");
+
+ KStdAction::preferences(this, SLOT(configure()), actionCollection());
+
+ bookmarkMenu = new KActionMenu(i18n("&Bookmarks"), "bookmarks", actionCollection(), "bookmarks");
+ KJotsBookmarks* bookmarks = new KJotsBookmarks(this);
+ connect(bookmarks, SIGNAL(openPage(const QString&)), SLOT(jumpToBookmark(const QString&)));
+ new KBookmarkMenu(KBookmarkManager::managerForFile(locateLocal("appdata","bookmarks.xml")),
+ bookmarks, bookmarkMenu->popupMenu(),
+ actionCollection(), true);
+ setupGUI();
+ /*
+ * TODO: add a bookmark bar, something like this
+ KToolBar* bar = dynamic_cast<KToolBar *>(child("bookmarkToolBar", "KToolBar"));
+ new KBookmarkBar(KBookmarkManager::managerForFile(locateLocal("appdata","bookmarks.xml")),
+ bookmarks, bar, actionCollection(), this, "BookmarkBar");
+ if (bar->count() == 0)
+ {
+ bar->hide();
+ }
+ */
+
+ m_autosaveTimer = new QTimer(this, "autosave_timer");
+
+ //
+ // Set startup size.
+ //
+ if (!KJotsSettings::splitterSizes().isEmpty())
+ {
+ splitter->setSizes(KJotsSettings::splitterSizes());
+ }
+
+ //
+ // Now load the books
+ //
+ loadBooks();
+
+ updateConfiguration();
+ updateMenu();
+
+ QTimer::singleShot(0, this, SLOT(slotSetupInterface()));
+
+ //connect new slots
+ connect(subjectList, SIGNAL(selectionChanged(QListViewItem*)),
+ this, SLOT(jumpToEntry(QListViewItem*)));
+ connect(subjectList, SIGNAL(moved(QListViewItem*, QListViewItem*, QListViewItem*)),
+ this, SLOT(slotItemMoved(QListViewItem*, QListViewItem*, QListViewItem*)));
+ connect(subjectList, SIGNAL(expanded(QListViewItem*)),
+ this, SLOT(slotExpandBook(QListViewItem*)));
+ connect(subjectList, SIGNAL(collapsed(QListViewItem*)),
+ this, SLOT(slotCollapseBook(QListViewItem*)));
+ connect(subjectList, SIGNAL(contextMenu(KListView*,QListViewItem*,const QPoint&)),
+ this, SLOT(showListviewContextMenu(KListView*,QListViewItem*,const QPoint&)));
+ connect(subjectList, SIGNAL(itemRenamed(QListViewItem*,const QString&,int)),
+ this, SLOT(slotItemRenamed(QListViewItem*,const QString&,int)));
+ connect(roTextView, SIGNAL(urlClick(const QString&)),
+ this, SLOT(linkClicked(const QString&)));
+ connect(m_autosaveTimer, SIGNAL(timeout()),
+ this, SLOT(autoSave()));
+}
+
+void KJotsMain::slotSetupInterface()
+{
+ if (subjectList->childCount() == 0)
+ {
+ if ( !createNewBook() )
+ {
+ roTextView->clear();
+ textStack->raiseWidget(roTextView);
+ }
+ }
+}
+
+/*!
+ \brief Loads all the books it can find in the appdata directory.
+ Needless to say: this should only ever be called once.
+*/
+void KJotsMain::loadBooks()
+{
+ QDir dir(locateLocal("appdata",""));
+ QStringList files = dir.entryList(QDir::Files|QDir::Readable);
+ Q_UINT64 currentSelection = KJotsSettings::currentSelection();
+
+ //TODO: Eventually we can make use of the ".book" extension here, but for
+ //right now (2005/06/04) there's just too much legacy data out there.
+
+ for (QStringList::Iterator it = files.begin(); it != files.end(); it++)
+ {
+ QString filepath = dir.absFilePath(*it);
+
+ if (!KJotsBook::isBookFile(filepath) )
+ {
+ continue;
+ }
+
+ KJotsBook* book = new KJotsBook(subjectList, 0);
+ book->openBook(filepath);
+ }
+
+ QListViewItemIterator it( subjectList );
+ while ( it.current() ) {
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(it.current());
+ if ( entry && entry->id() == currentSelection )
+ {
+ subjectList->ensureItemVisible(entry);
+ subjectList->setSelected(entry, true);
+ jumpToEntry(entry);
+ break;
+ }
+ ++it;
+ }
+
+ return;
+}
+
+bool KJotsMain::createNewBook()
+{
+ bool ok;
+
+ QString name = KInputDialog::getText( i18n( "New Book" ),
+ i18n( "Book name:" ), QString::null, &ok, this );
+
+ if (!ok)
+ return false;
+
+ KJotsBook* book = new KJotsBook(subjectList, 0);
+ book->setSubject(name);
+ book->openBook("");
+ book->setOpen(true);
+ subjectList->setSelected(book->firstChild(), true);
+ return true;
+}
+
+void KJotsMain::slotRenameEntry()
+{
+ KJotsEntryBase* entry = dynamic_cast<KJotsEntryBase*>(subjectList->currentItem());
+
+ if (entry)
+ {
+ entry->rename();
+ jumpToEntry(entry, true); //reflect the changes on screen
+ }
+}
+
+void KJotsMain::deleteBook()
+{
+ KJotsBook* b = currentBook();
+
+ if (!b)
+ return;
+
+ QString msg = i18n("<qt>Are you sure you want to delete the <strong>%1</strong> book?</qt>");
+ int result = KMessageBox::warningContinueCancel(topLevelWidget(), msg.arg(b->subject()), i18n("Delete Book"),KStdGuiItem::del());
+
+ if (result!=KMessageBox::Continue)
+ return;
+
+ KJotsBook* nxt=dynamic_cast<KJotsBook*>(b->nextSibling());
+
+ b->deleteBook();
+ currentEntry = 0L;
+ delete b;
+
+ if (!nxt)
+ nxt=dynamic_cast<KJotsBook*>(subjectList->firstChild());
+
+ if (nxt)
+ {
+ subjectList->setSelected(nxt, true);
+ }
+ else
+ {
+ roTextView->clear();
+ textStack->raiseWidget(roTextView);
+ updateMenu();
+ }
+}
+
+void KJotsMain::newEntry()
+{
+ KJotsBook* b = currentBook();
+
+ if (b)
+ {
+ KJotsPage* s = b->addPage();
+ subjectList->setSelected(s, true);
+ }
+}
+
+void KJotsMain::deleteEntry()
+{
+ KJotsPage* cur = currentPage();
+
+ if (!cur ||
+ KMessageBox::warningContinueCancel(topLevelWidget(),
+ i18n("<qt>Are you sure you want to delete the <strong>%1</strong> page?</qt>")
+ .arg(cur->subject()),
+ i18n("Delete Page"),KStdGuiItem::del()) != KMessageBox::Continue)
+ {
+ return;
+ }
+
+ KJotsBook* bk = cur->parentBook();
+ KJotsPage* nxt = dynamic_cast<KJotsPage*>(cur->nextSibling());
+
+ me_text->setEntry(0);
+ delete cur;
+ currentEntry = 0;
+
+ if (!nxt)
+ nxt = dynamic_cast<KJotsPage*>(bk->firstChild());
+
+ if (nxt)
+ {
+ subjectList->setSelected(nxt, true);
+ } else {
+ subjectList->setSelected(bk, true);
+ }
+
+ updateMenu();
+}
+
+void KJotsMain::configure()
+{
+ if(KConfigDialog::showDialog("settings"))
+ return;
+
+ KConfigDialog* dialog = new KConfigDialog(this, "settings", KJotsSettings::self());
+
+ confPageFont* cpFont = new confPageFont(0, "Font");
+ dialog->addPage(cpFont, i18n("Font"), "fonts");
+
+ confPageMisc* cpMisc = new confPageMisc(0, "Autosave");
+ dialog->addPage(cpMisc, i18n("Autosave"), "misc");
+
+ connect(dialog, SIGNAL(settingsChanged()), this, SLOT(updateConfiguration()));
+
+ dialog->show();
+}
+
+void KJotsMain::slotSearch()
+{
+ me_text->search();
+}
+
+void KJotsMain::slotRepeatSearch()
+{
+ me_text->repeatSearch();
+}
+
+void KJotsMain::slotReplace()
+{
+ me_text->replace();
+}
+
+void KJotsMain::updateConfiguration()
+{
+ static int encoding = -1;
+
+ //Keep track of the encoding setting. If the user changes it, we
+ //need to mark all books dirty so they are saved correctly.
+ if ( encoding == -1 ) {
+ encoding = KJotsSettings::unicode();
+ } else {
+ if ( (int)encoding != KJotsSettings::unicode() ) {
+ KJotsBook *book = dynamic_cast<KJotsBook*>(subjectList->firstChild());
+ while (book) {
+ book->setDirty(true);
+ book = dynamic_cast<KJotsBook*>(book->nextSibling());
+ }
+
+ encoding = (int)KJotsSettings::unicode();
+ }
+ }
+
+ me_text->setFont(KJotsSettings::font());
+ if (KJotsSettings::autoSave())
+ m_autosaveTimer->changeInterval(KJotsSettings::autoSaveInterval()*1000*60);
+ else
+ m_autosaveTimer->stop();
+}
+
+/*!
+ \brief Saves any books that need saving.
+*/
+void KJotsMain::autoSave()
+{
+ KJotsBook *book = dynamic_cast<KJotsBook*>(subjectList->firstChild());
+ while (book)
+ {
+ if ( book->isDirty() )
+ {
+ book->saveBook();
+ }
+
+ book = dynamic_cast<KJotsBook*>(book->nextSibling());
+ }
+}
+
+void KJotsMain::writeBook()
+{
+ saveBookToFile(true);
+}
+
+void KJotsMain::writeBookToHTML()
+{
+ saveBookToFile(false);
+}
+
+void KJotsMain::saveBookToFile(bool plainText)
+{
+ KJotsBook* b = currentBook();
+
+ if (!b)
+ return;
+
+ bool tryAgain = true;
+ KEncodingFileDialog::Result res;
+ while (tryAgain)
+ {
+
+ res = KEncodingFileDialog::getSaveURLAndEncoding();
+
+ if (res.URLs[0].isEmpty())
+ {
+ tryAgain = false;
+ }
+
+ if (!KIO::NetAccess::exists(res.URLs[0], true, this) ||
+ KMessageBox::warningYesNo(this, "<qt>" + i18n("The file <strong>%1</strong> already exists. Do you wish to overwrite it?").arg(res.URLs[0].prettyURL()) + "</qt>", i18n("File Exists"), i18n("Overwrite"), KStdGuiItem::cancel()) == KMessageBox::Yes)
+ {
+ tryAgain = false;
+ }
+ }
+
+ if (!res.URLs[0].isEmpty())
+ {
+ b->saveToFile(res.URLs[0], plainText, res.encoding);
+ }
+}
+
+void KJotsMain::writePage()
+{
+ savePageToFile(true);
+}
+
+void KJotsMain::writePageToHTML()
+{
+ savePageToFile(false);
+}
+
+void KJotsMain::savePageToFile(bool plainText)
+{
+ KJotsPage* e = currentPage();
+
+ if (!e)
+ return;
+
+ bool tryAgain = true;
+ KEncodingFileDialog::Result res;
+ while (tryAgain)
+ {
+ res = KEncodingFileDialog::getSaveURLAndEncoding();
+
+ if (res.URLs[0].isEmpty())
+ {
+ tryAgain = false;
+ }
+
+ if (!KIO::NetAccess::exists(res.URLs[0], true, this) ||
+ KMessageBox::warningYesNo(this, "<qt>" + i18n("The file <strong>%1</strong> already exists. Do you wish to overwrite it?").arg(res.URLs[0].prettyURL()) + "</qt>", i18n("File Exists"), i18n("Overwrite"), KStdGuiItem::cancel()) == KMessageBox::Yes)
+ {
+ tryAgain = false;
+ }
+ }
+
+ if (!res.URLs[0].isEmpty())
+ {
+ e->saveToFile(res.URLs[0], plainText, res.encoding);
+ }
+}
+
+void KJotsMain::copySelection()
+{
+ //TODO: Strip HTML tags
+ KJotsPage* cur = currentPage();
+
+ if (cur && me_text->hasSelectedText())
+ cur->setSubject(me_text->selectedText());
+}
+
+void KJotsMain::slotPrint()
+{
+ autoSave();
+ KJotsEntryBase* entry = dynamic_cast<KJotsEntryBase*>(subjectList->currentItem());
+
+ if (entry)
+ {
+ entry->print(m_font);
+ }
+}
+
+void KJotsMain::slotQuit()
+{
+ close();
+}
+
+void KJotsMain::insertDate()
+{
+ me_text->insert(KGlobal::locale()->formatDateTime(QDateTime::currentDateTime(), true) + " ");
+}
+
+void KJotsMain::updateMenu()
+{
+ KJotsEntryBase* cur = dynamic_cast<KJotsEntryBase*>(subjectList->currentItem());
+
+ if (!cur)
+ {
+ // no (meaningful?) selection
+ actions[ACTION_DELETE_BOOK]->setEnabled(false);
+ actions[ACTION_DELETE_PAGE]->setEnabled(false);
+ actions[ACTION_NEW_PAGE]->setEnabled(false);
+ actions[ACTION_PRINT]->setEnabled(false);
+ actions[ACTION_CUT]->setEnabled(false);
+ actions[ACTION_PASTE]->setEnabled(false);
+ actions[ACTION_FIND]->setEnabled(false);
+ actions[ACTION_REPLACE]->setEnabled(false);
+ actions[ACTION_BOOK2TEXT]->setEnabled(false);
+ actions[ACTION_BOOK2HTML]->setEnabled(false);
+ actions[ACTION_PAGE2TEXT]->setEnabled(false);
+ actions[ACTION_PAGE2HTML]->setEnabled(false);
+ actions[ACTION_RENAME]->setEnabled(false);
+ actions[ACTION_INSERT_DATE]->setEnabled(false);
+ actions[ACTION_NEXT_BOOK]->setEnabled(false);
+ actions[ACTION_PREV_BOOK]->setEnabled(false);
+ actions[ACTION_NEXT_PAGE]->setEnabled(false);
+ actions[ACTION_PREV_PAGE]->setEnabled(false);
+ actions[ACTION_MANUAL_SAVE]->setEnabled(false);
+ bookmarkMenu->setEnabled(false);
+ exportPageMenu->setEnabled(false);
+ exportBookMenu->setEnabled(false);
+ }
+ else
+ {
+ actions[ACTION_DELETE_BOOK]->setEnabled(true);
+ actions[ACTION_NEW_PAGE]->setEnabled(true);
+ actions[ACTION_PRINT]->setEnabled(true);
+ actions[ACTION_FIND]->setEnabled(true);
+ actions[ACTION_BOOK2TEXT]->setEnabled(true);
+ actions[ACTION_BOOK2HTML]->setEnabled(true);
+ actions[ACTION_RENAME]->setEnabled(true);
+ actions[ACTION_MANUAL_SAVE]->setEnabled(true);
+ bookmarkMenu->setEnabled(true);
+ exportBookMenu->setEnabled(true);
+
+ //TODO: Only activate if there is a next/prev book/page.
+ actions[ACTION_NEXT_BOOK]->setEnabled(true);
+ actions[ACTION_PREV_BOOK]->setEnabled(true);
+ actions[ACTION_NEXT_PAGE]->setEnabled(true);
+ actions[ACTION_PREV_PAGE]->setEnabled(true);
+
+ if ( cur->isBook() )
+ {
+ actions[ACTION_CUT]->setEnabled(false);
+ actions[ACTION_PASTE]->setEnabled(false);
+ actions[ACTION_REPLACE]->setEnabled(false);
+ actions[ACTION_DELETE_PAGE]->setEnabled(false);
+ actions[ACTION_PAGE2TEXT]->setEnabled(false);
+ actions[ACTION_PAGE2HTML]->setEnabled(false);
+ actions[ACTION_INSERT_DATE]->setEnabled(false);
+ exportPageMenu->setEnabled(false);
+ }
+ else
+ {
+ actions[ACTION_PASTE]->setEnabled(true);
+ actions[ACTION_REPLACE]->setEnabled(true);
+ actions[ACTION_DELETE_PAGE]->setEnabled(true);
+ actions[ACTION_PAGE2TEXT]->setEnabled(true);
+ actions[ACTION_PAGE2HTML]->setEnabled(true);
+ actions[ACTION_INSERT_DATE]->setEnabled(true);
+ exportPageMenu->setEnabled(true);
+ }
+ }
+}
+
+void KJotsMain::slotFindSuccessful()
+{
+ actions[ACTION_FIND_NEXT]->setEnabled(true);
+}
+
+void KJotsMain::showListviewContextMenu(KListView*, QListViewItem* i, const QPoint& p)
+{
+ if ( invalidMoveFlag ) return; //Prevent race condition
+ KActionMenu* am = new KActionMenu(this);
+
+ if (!i)
+ {
+ // clicked on empty space
+ am->insert(actions[ACTION_NEW_BOOK]);
+ }
+ else if (dynamic_cast<KJotsBook*>(i))
+ {
+ // clicked on book
+ am->insert(actions[ACTION_NEW_PAGE]);
+ am->insert(actions[ACTION_RENAME]);
+ am->insert(exportBookMenu);
+ am->insert(new KActionSeparator(am));
+ am->insert(actions[ACTION_DELETE_BOOK]);
+ }
+ else
+ {
+ //clicked on page
+ am->insert(actions[ACTION_NEW_PAGE]);
+ am->insert(actions[ACTION_RENAME]);
+ am->insert(exportPageMenu);
+ am->insert(new KActionSeparator(am));
+ am->insert(actions[ACTION_DELETE_PAGE]);
+ }
+
+ am->popup(p);
+}
+
+/*!
+ \brief Handle link clicks in read-only HTML view
+ All URL clicks in the read-only window come here. For some reason
+ KTextBrowser doesn't handle anchor links itself, so we have to take
+ care of those, too.
+*/
+void KJotsMain::linkClicked(const QString& link)
+{
+ if (link[0] == '#')
+ {
+ // internal link from TOC
+ roTextView->scrollToAnchor(link.mid(1));
+ return;
+ }
+
+ Q_UINT64 target = link.toULongLong();
+ QListViewItemIterator it( subjectList );
+ while ( it.current() ) {
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(it.current());
+ if ( entry && entry->id() == target )
+ {
+ subjectList->ensureItemVisible(entry);
+ subjectList->setSelected(entry, true);
+ jumpToEntry(entry);
+ break;
+ }
+ ++it;
+ }
+
+ return;
+}
+
+bool KJotsMain::queryClose()
+{
+ autoSave();
+ saveProperties();
+ return true;
+}
+
+/*!
+ \brief Saves settings to the ini-like config file.
+ This function only needs to be called before program termination.
+*/
+void KJotsMain::saveProperties()
+{
+ KJotsSettings::setSplitterSizes(splitter->sizes());
+
+ KJotsEntryBase* entry = dynamic_cast<KJotsEntryBase*>(subjectList->currentItem());
+ KJotsSettings::setCurrentSelection( entry ? entry->id() : 0);
+
+ KJotsSettings::writeConfig();
+ return;
+}
+
+/*!
+ \brief Called when a book is opened/expanded/whatever.
+*/
+void KJotsMain::slotExpandBook(QListViewItem *item)
+{
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(item);
+ if ( entry ) entry->setDirty(true);
+}
+
+/*!
+ \brief Called when a book is closed/collapsed/whatever.
+*/
+void KJotsMain::slotCollapseBook(QListViewItem *item)
+{
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(item);
+ if ( entry ) entry->setDirty(true);
+}
+
+/*!
+ Returns the name of the active book or page.
+*/
+QString KJotsMain::currentBookmarkTitle()
+{
+ QString title;
+ QListViewItem *item = subjectList->currentItem();
+
+ while ( item )
+ {
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(item);
+ item = item->parent();
+
+ if ( item )
+ {
+ title = ": " + entry->subject() + title;
+ } else {
+ title = entry->subject() + title;
+ }
+ }
+
+ return title;
+}
+
+/*!
+ Returns a bookmark that identifies the active book or page.
+*/
+QString KJotsMain::currentBookmarkURL()
+{
+ QString url;
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(subjectList->currentItem());
+
+ if ( entry )
+ {
+ url.setNum( entry->id() );
+ }
+
+ return url;
+}
+
+/*!
+ Accepts a bookmark from the bookmark manager and jumps to the given entry.
+ \param bookmark The bookmark.
+*/
+void KJotsMain::jumpToBookmark(const QString& bookmark)
+{
+ Q_UINT64 id = bookmark.toULongLong();
+
+ if ( id )
+ {
+ QListViewItemIterator it( subjectList );
+ while ( it.current() ) {
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(it.current());
+ if ( entry && entry->id() == id )
+ {
+ subjectList->ensureItemVisible(entry);
+ subjectList->setSelected(entry, true);
+ jumpToEntry(entry);
+ break;
+ }
+ ++it;
+ }
+ } else {
+ //This is an old bookmark. Warn, and then continue. This can all be removed at some point
+ //in the future. CREATION DATE: 2005/06/10
+
+ KMessageBox::information(this,
+ i18n("This bookmark is from an older version of KJots and is not fully supported. It may or may not work. You should delete and recreate this bookmark."), QString::null, "oldBookmarkWarning");
+
+ int slash = bookmark.findRev('/');
+
+ if (slash != -1)
+ {
+ QString bookName = bookmark.left(slash);
+ int pageNo = bookmark.mid(slash+1).toInt();
+ int pageCount = 0;
+
+ //First, find the book. It'll only be root-level.
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(subjectList->firstChild());
+
+ while (entry)
+ {
+ if ( entry->subject() == bookName )
+ {
+ break;
+ }
+ entry = dynamic_cast<KJotsEntryBase*>(entry->nextSibling());
+ }
+
+ if ( !entry ) return;
+
+ if ( !pageNo )
+ {
+ subjectList->setSelected(entry, true);
+ jumpToEntry(entry);
+ } else {
+ //Now, find the right page
+ entry = dynamic_cast<KJotsEntryBase*>(entry->firstChild());
+
+ while (entry)
+ {
+ KJotsPage *page = dynamic_cast<KJotsPage*>(entry);
+
+ if ( page )
+ {
+ if ( ++pageCount == pageNo )
+ {
+ static_cast<QListViewItem*>(entry)->parent()->setOpen(true);
+ subjectList->ensureItemVisible(entry);
+ subjectList->setSelected(entry, true);
+ jumpToEntry(entry);
+ break;
+ }
+ }
+
+ entry = dynamic_cast<KJotsEntryBase*>(entry->nextSibling());
+ }
+ }
+ }
+ }
+}
+
+/*!
+ \brief Moves to the next book after the current selection.
+*/
+void KJotsMain::nextBook()
+{
+ QListViewItem *item = subjectList->currentItem();
+ if ( !item ) return; //sanity check
+
+ QListViewItemIterator it ( item );
+ QListViewItemIterator start ( it );
+
+ do {
+ it++;
+
+ //if we iterate off the list, start over again.
+ if ( !it.current() )
+ {
+ it = QListViewItemIterator ( subjectList );
+ }
+
+ if ( it.current() == start.current() ) return; //Bail out if we loop.
+ } while ( !dynamic_cast<KJotsBook*>(it.current()));
+
+ subjectList->ensureItemVisible(it.current());
+ subjectList->setSelected(it.current(), true);
+
+ return;
+}
+
+/*!
+ \brief Moves to the previous book before the current selection.
+*/
+void KJotsMain::prevBook()
+{
+ //Don't get caught by parent book.
+ QListViewItem *startingPoint = subjectList->currentItem();
+ if ( !startingPoint ) return; //sanity check
+
+ if ( dynamic_cast<KJotsPage*>(startingPoint) )
+ startingPoint = startingPoint->parent();
+
+ QListViewItemIterator it ( startingPoint );
+ do {
+ it--;
+
+ //if we iterate off the list, start over again.
+ if ( !it.current() )
+ {
+ it = QListViewItemIterator ( subjectList->lastItem() );
+ }
+
+ if ( it.current() == startingPoint ) return; //Bail out if we loop.
+ } while ( !dynamic_cast<KJotsBook*>(it.current()));
+
+ subjectList->ensureItemVisible(it.current());
+ subjectList->setSelected(it.current(), true);
+
+ return;
+}
+
+/*!
+ \brief Moves to the next page after the current selection.
+*/
+void KJotsMain::nextPage()
+{
+ QListViewItem *item = subjectList->currentItem();
+ if ( !item ) return; //sanity check
+
+ QListViewItemIterator it ( item );
+ QListViewItemIterator start ( it );
+
+ do {
+ it++;
+
+ //if we iterate off the list, start over again.
+ if ( !it.current() )
+ {
+ it = QListViewItemIterator ( subjectList );
+ }
+
+ if ( it.current() == start.current() ) return; //Bail out if we loop.
+ } while ( !dynamic_cast<KJotsPage*>(it.current()));
+
+ subjectList->ensureItemVisible(it.current());
+ subjectList->setSelected(it.current(), true);
+
+ return;
+}
+
+/*!
+ \brief Moves to the previous page before the current selection.
+*/
+void KJotsMain::prevPage()
+{
+ QListViewItem *item = subjectList->currentItem();
+ if ( !item ) return; //sanity check
+
+ QListViewItemIterator it ( item );
+ QListViewItemIterator start ( it );
+
+ do {
+ it--;
+
+ //if we iterate off the list, start over again.
+ if ( !it.current() )
+ {
+ it = QListViewItemIterator ( subjectList->lastItem() );
+ }
+
+ if ( it.current() == start.current() ) return; //Bail out if we loop.
+ } while ( !dynamic_cast<KJotsPage*>(it.current()));
+
+ subjectList->ensureItemVisible(it.current());
+ subjectList->setSelected(it.current(), true);
+
+ return;
+}
+
+void KJotsMain::jumpToEntry(QListViewItem* entry, bool force)
+{
+ //This won't lose data or anything; but it does reset the cursor postion and waste cycles.
+ if (currentEntry == entry && !force)
+ return;
+
+ if (entry == 0)
+ {
+ me_text->setEntry(0);
+ currentEntry = 0;
+ }
+ else if (dynamic_cast<KJotsBook*>(entry))
+ {
+ me_text->setEntry(0); //clear any old data
+
+ KJotsBook* book = static_cast<KJotsBook*>(entry);
+ QString html = book->generateHtml(book, false);
+
+ roTextView->setText(html);
+ roTextView->setCursorPosition(0, 0);
+ textStack->raiseWidget(roTextView);
+ currentEntry = 0;
+ }
+ else
+ {
+ textStack->raiseWidget(me_text);
+ me_text->setEntry(dynamic_cast<KJotsPage*>(entry));
+ currentEntry = static_cast<KJotsEntryBase*>(entry);
+ }
+
+ updateCaption();
+ updateMenu();
+}
+
+/*!
+ Sets the window caption.
+*/
+void KJotsMain::updateCaption()
+{
+ QString caption;
+ QListViewItem *item = subjectList->currentItem();
+
+ while ( item )
+ {
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(item);
+ item = item->parent();
+
+ if ( item )
+ {
+ caption = " / " + entry->subject() + caption;
+ } else {
+ caption = entry->subject() + caption;
+ }
+ }
+
+ setCaption(kapp->makeStdCaption(caption));
+ return;
+}
+
+void KJotsMain::slotItemRenamed(QListViewItem* item, const QString& str, int /*col*/)
+{
+ KJotsEntryBase* entry = dynamic_cast<KJotsEntryBase*>(item);
+
+ if (entry)
+ {
+ entry->setSubject(str);
+ entry->setDirty(true);
+ updateCaption();
+ jumpToEntry(entry, true); //reflect the changes on screen
+ }
+}
+
+/*!
+ \brief Called when an item is moved via drag-and-drop.
+ \warning The whole drag-n-drop reordering system is completely booched.
+ Tread lightly and test well when modifying things here.
+*/
+void KJotsMain::slotItemMoved(QListViewItem *item, QListViewItem* afterFirst, QListViewItem */*afterNow*/ )
+{
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(item);
+
+ //afterFirst doesn't work like we need it to. We want it to point to the
+ //previous sibling, not just the entry directly above it.
+ if ( afterFirst && afterFirst->parent() != entry->parentBook() )
+ {
+ QListViewItemIterator it ( afterFirst );
+ afterFirst = 0;
+
+ //Rewind backwards up the tree...
+ while ( it.current() )
+ {
+ //No other items were above this one.
+ if ( it.current() == entry->parentBook() )
+ {
+ break;
+ }
+
+ //Found a previous sibling!
+ if ( it.current()->parent() == entry->parentBook() )
+ {
+ afterFirst = it.current();
+ break;
+ }
+
+ --it;
+ }
+ }
+
+ KJotsEntryBase *entryAfter = dynamic_cast<KJotsEntryBase*>(afterFirst);
+
+ if ( entry->isPage() && !item->parent() )
+ {
+ invalidMoveFlag=true; //Don't do anything while we're stuck here.
+ subjectList->setItemsMovable(false);
+ subjectList->setItemsRenameable(false);
+
+ // We don't accept pages in the root. Create a new book?
+ if (KMessageBox::questionYesNo(this,
+ i18n("All pages must be inside a book. "
+ "Would you like to create a new book to put the page in, "
+ "or would you prefer to not move the page at all?"),
+ QString::null,
+ i18n("Create New Book"), i18n("Do Not Move Page")) ==
+ KMessageBox::No ||
+ !createNewBook())
+ {
+ //We have to move item back.
+ subjectList->takeItem(item);
+ entry->parentBook()->insertItem(item);
+ entry->moveItem(afterFirst);
+ } else {
+ subjectList->takeItem(item);
+ delete currentBook()->firstChild();
+ currentBook()->insertItem(item);
+ subjectList->ensureItemVisible(item);
+ subjectList->setSelected(item, true);
+ }
+
+ invalidMoveFlag=false;
+ subjectList->setItemsMovable(true);
+ subjectList->setItemsRenameable(true);
+ }
+
+ if ( entry )
+ {
+ entry->resetParent();
+ entry->setDirty(true);
+ }
+
+ if ( entryAfter )
+ {
+ //Set the old parent book to dirty, since it just lost a page.
+ if ( entryAfter->isBook() )
+ entryAfter->setDirty(true);
+ else
+ entryAfter->parentBook()->setDirty(true);
+ }
+
+ return;
+}
+
+/*!
+ Returns a pointer to the currently selected book, or the book that owns
+ the currently selected page.
+*/
+KJotsBook* KJotsMain::currentBook()
+{
+ KJotsEntryBase* e = dynamic_cast<KJotsEntryBase*>(subjectList->currentItem());
+
+ while (e)
+ {
+ if (dynamic_cast<KJotsBook*>(e))
+ {
+ return dynamic_cast<KJotsBook*>(e);
+ }
+ e = dynamic_cast<KJotsEntryBase*>(e->KListViewItem::parent());
+ }
+
+ return 0;
+}
+
+/*!
+ Returns the currently selected page or 0 if no page is selected.
+*/
+KJotsPage* KJotsMain::currentPage()
+{
+ return dynamic_cast<KJotsPage*>(subjectList->currentItem());
+}
+
+void addBookmark()
+{
+}
+
+void editBookmarks()
+{
+}
+
+#include "KJotsMain.moc"
+/* ex: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab: */
diff --git a/kjots/KJotsMain.h b/kjots/KJotsMain.h
new file mode 100644
index 0000000..28ec089
--- /dev/null
+++ b/kjots/KJotsMain.h
@@ -0,0 +1,165 @@
+//
+// kjots
+//
+// Copyright (C) 1997 Christoph Neerfeld
+// Copyright (C) 2002-2004 Aaron J. Seigo
+// Copyright (C) 2003 Stanislav Kljuhhin
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef KJotsMain_included
+#define KJotsMain_included
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+
+#include <kdialogbase.h>
+#include <kmainwindow.h>
+
+class QGroupBox;
+class QWidgetStack;
+class KTextBrowser;
+class KAccel;
+class KJotsMain;
+class KToolBar;
+class KListBox;
+class KListView;
+class KPopupMenu;
+class ConfigureDialog;
+class KEdFind;
+class KEdReplace;
+class QTimer;
+class KAction;
+class KActionMenu;
+
+class KJotsPage;
+class KJotsBook;
+class KJotsEntryBase;
+class KJotsEdit;
+
+//
+// KJotsMain
+//
+#define ACTION_NEXT_BOOK 0
+#define ACTION_PREV_BOOK 1
+#define ACTION_NEXT_PAGE 2
+#define ACTION_PREV_PAGE 3
+#define ACTION_NEW_PAGE 4
+#define ACTION_NEW_BOOK 5
+#define ACTION_PAGE2TEXT 6
+#define ACTION_PAGE2HTML 7
+#define ACTION_BOOK2TEXT 8
+#define ACTION_BOOK2HTML 9
+#define ACTION_DELETE_PAGE 10
+#define ACTION_DELETE_BOOK 11
+#define ACTION_MANUAL_SAVE 12
+#define ACTION_PRINT 13
+#define ACTION_QUIT 14
+#define ACTION_CUT 15
+#define ACTION_COPY 16
+#define ACTION_PASTE2TITLE 17
+#define ACTION_PASTE 18
+#define ACTION_FIND 19
+#define ACTION_FIND_NEXT 20
+#define ACTION_REPLACE 21
+#define ACTION_RENAME 22
+#define ACTION_INSERT_DATE 23
+#define ACTION_MAX 24
+
+class KJotsMain : public KMainWindow
+{
+ Q_OBJECT
+
+ public:
+ KJotsMain( const char* name = 0 );
+
+ QString currentBookmarkTitle();
+ QString currentBookmarkURL();
+
+ public:
+ void updateCaption();
+
+ protected slots:
+ void slotSetupInterface();
+ bool createNewBook();
+ void deleteBook();
+ void newEntry();
+ void deleteEntry();
+ void slotRenameEntry();
+ void configure();
+ void updateConfiguration();
+
+ void copySelection();
+ void insertDate();
+ void slotPrint();
+ void slotSearch();
+ void slotRepeatSearch();
+ void slotReplace();
+ void slotQuit();
+ void slotFindSuccessful();
+
+ void jumpToEntry(QListViewItem* entry, bool=false);
+
+ void slotExpandBook(QListViewItem* item);
+ void slotCollapseBook(QListViewItem* item);
+ void slotItemRenamed(QListViewItem*,const QString&,int);
+ void slotItemMoved(QListViewItem*,QListViewItem*,QListViewItem*);
+ void writeBook();
+ void writeBookToHTML();
+ void saveBookToFile(bool plainText);
+ void writePage();
+ void writePageToHTML();
+ void savePageToFile(bool plainText);
+
+ void nextBook();
+ void prevBook();
+ void nextPage();
+ void prevPage();
+
+ // handling page changes in the listview
+ void showListviewContextMenu(KListView* l, QListViewItem* i, const QPoint& p);
+ void linkClicked(const QString&);
+ void autoSave(void);
+
+ // bookmarks
+ void jumpToBookmark(const QString& page);
+
+ protected:
+ void saveProperties();
+ bool queryClose();
+ void updateMenu();
+ void loadBooks();
+ KJotsBook* currentBook();
+ KJotsPage* currentPage();
+
+ QHBoxLayout *bg_top_layout;
+ QButtonGroup *bg_top;
+ KJotsEdit *me_text;
+ KTextBrowser *roTextView;
+ KListView *subjectList;
+ KJotsEntryBase *currentEntry;
+ QSplitter *splitter;
+ QWidgetStack *textStack;
+ QFont m_font;
+ QTimer* m_autosaveTimer;
+ bool invalidMoveFlag; //!< Used to fix a race condition. See Bug #109299
+
+ KAction* actions[ACTION_MAX];
+ KActionMenu *exportPageMenu, *exportBookMenu, *bookmarkMenu;
+};
+
+#endif // KJotsMain_included
+/* ex: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab: */
diff --git a/kjots/KJotsSettings.kcfgc b/kjots/KJotsSettings.kcfgc
new file mode 100644
index 0000000..44b75cc
--- /dev/null
+++ b/kjots/KJotsSettings.kcfgc
@@ -0,0 +1,8 @@
+# Code generation options for kconfig_compiler
+File=kjots.kcfg
+ClassName=KJotsSettings
+Singleton=true
+Mutators=Width,Height,SplitterSizes,CurrentSelection,OpenBooks,LastId
+# Inherits=KConfigSkeleton
+# IncludeFiles=libkdepim/kpimprefs.h
+# MemberVariables=public
diff --git a/kjots/Kjots.desktop b/kjots/Kjots.desktop
new file mode 100644
index 0000000..b0550e0
--- /dev/null
+++ b/kjots/Kjots.desktop
@@ -0,0 +1,80 @@
+[Desktop Entry]
+DocPath=kjots/index.html
+Name=KJots
+Name[af]=Kjots
+Name[eo]=Notlibro
+Name[hi]=के-जॉट्स
+Name[hr]=Bilješke
+Name[pt_BR]=Tomador de notas
+Name[sv]=Kjots
+Name[ta]= KJots
+Name[th]=บันทึกช่วยจำ
+Name[xh]=Amaxabiso amancinane e K
+GenericName=Note Taker
+GenericName[af]=Nota Afnemer
+GenericName[ar]=برنامج لأخذ الملاحظات
+GenericName[bg]=Бележки
+GenericName[bs]=Uzimanje bilješki
+GenericName[ca]=Anotador
+GenericName[cs]=Poznámkový blok
+GenericName[cy]=Cofnodydd
+GenericName[da]=Notetager
+GenericName[de]=Notizen machen
+GenericName[el]=Καταγραφέας σημειώσεων
+GenericName[eo]=Notolibro
+GenericName[es]=Para tomar notas
+GenericName[et]=Märkmete tegemine
+GenericName[eu]=Ohar Hartzailea
+GenericName[fa]=یادداشت بردار
+GenericName[fi]=Muistilappuohjelma
+GenericName[fr]=Prise de notes
+GenericName[ga]=Eagarthóir Nótaí
+GenericName[he]=כותב הערות
+GenericName[hi]=नोट टेकर
+GenericName[hr]=Program za pisanje bilježaka
+GenericName[hu]=Jegyzetlapok
+GenericName[is]=Minnispunktar
+GenericName[it]=Blocco per appunti
+GenericName[ja]=メモを取る
+GenericName[kk]=Шағын дәптер
+GenericName[km]=កម្មវិធី​កត់ចំណាំNote Taker
+GenericName[lt]=Pastabų gavėjas
+GenericName[lv]=Piezīmju Ņēmējs
+GenericName[mk]=Прибележувач
+GenericName[ms]=Pengambil Nota
+GenericName[mt]=Ħu noti
+GenericName[nb]=Beskjedverktøy
+GenericName[nds]=Notizen maken
+GenericName[ne]=टिपोट टेकर
+GenericName[nl]=Notitieboekje
+GenericName[nn]=Notatprogram
+GenericName[pa]=ਨੋਟ ਲਵੋ
+GenericName[pl]=Notatnik
+GenericName[pt]=Bloco de Notas
+GenericName[pt_BR]=Anotar pequenos apontamentos
+GenericName[ro]=Notiţe
+GenericName[ru]=Записная книжка
+GenericName[sk]=Ukladanie poznámok
+GenericName[sl]=Majhna beležnica
+GenericName[sr]=Прибележивач
+GenericName[sr@Latn]=Pribeleživač
+GenericName[sv]=Elektroniska anteckningar
+GenericName[ta]= குறிப்பு எடுப்பான்
+GenericName[tg]=Китобчаи Навиштаҷот
+GenericName[th]=บันทึกช่วยจำ
+GenericName[tr]=Not alıcı
+GenericName[uk]=Записна книжка
+GenericName[ven]=Mudzhii wa dzinotsi
+GenericName[wa]=Usteye po prinde des notes
+GenericName[xh]=Umthathi Womakuqwalaselwe
+GenericName[zh_CN]=笔记记录
+GenericName[zh_TW]=筆記簡記
+GenericName[zu]=Umthathi Wepheshana
+Icon=kjots
+Exec=kjots -caption "%c" %i %m
+Type=Application
+Path=
+Terminal=false
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Multi
+Categories=Qt;KDE;Utility;X-KDE-Utilities-PIM;
diff --git a/kjots/Makefile.am b/kjots/Makefile.am
new file mode 100644
index 0000000..32af728
--- /dev/null
+++ b/kjots/Makefile.am
@@ -0,0 +1,28 @@
+INCLUDES = $(all_includes)
+AM_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+LDADD = $(LIB_KFILE) $(LIB_KDEPRINT)
+
+bin_PROGRAMS = kjots
+
+kjots_SOURCES = main.cpp\
+ KJotsMain.cpp\
+ kjotsentry.cpp\
+ kjotsedit.cpp\
+ kjotsbookmarks.cpp\
+ confpagefont.ui\
+ confpagemisc.ui \
+ KJotsSettings.kcfgc
+
+kjots_METASOURCES = AUTO
+
+SUBDIRS = icons
+
+xdg_apps_DATA = Kjots.desktop
+kde_kcfg_DATA = kjots.kcfg
+
+rcdir = $(kde_datadir)/kjots
+rc_DATA = kjotsui.rc
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kjots.pot
+
diff --git a/kjots/README b/kjots/README
new file mode 100644
index 0000000..2ac51eb
--- /dev/null
+++ b/kjots/README
@@ -0,0 +1,33 @@
+kjots - a note taker
+------------------------------------
+
+(C) 2002, 2003 Aaron J. Seigo <[email protected]>
+
+(C) 1997 Christoph Neerfeld ([email protected])
+You may distribute kjots under the terms of the GNU General Public License.
+
+kjots is a small note taker program. Name and idea are taken from the jots
+program included in the tkgoodstuff package. The tkgoodstuff package is
+copyright (C) 1995-96 by Mark Crimmins ([email protected]).
+
+Features:
+ - you may create several folders to store small text notes
+
+Bugs:
+ - see the BUGS doc or http://bugs.kde.org
+
+TODO for 3.2:
+ - preserve ordering of books between reloads
+
+TODO for post 3.2:
+ - statusbar with e.g. timestamp of last mod
+ - allow formatting of text in notes
+ - allow trees of pages
+ - page templates (TODO, diary, etc)
+ - encryption of pages
+ - syncing w/handhelds
+
+Install:
+ see INSTALL for details
+
+If you find bugs or have suggestions, send me an email
diff --git a/kjots/confpagefont.ui b/kjots/confpagefont.ui
new file mode 100644
index 0000000..e89e5b5
--- /dev/null
+++ b/kjots/confpagefont.ui
@@ -0,0 +1,38 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>confPageFont</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>confPageFont</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>520</width>
+ <height>406</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Font</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="KFontChooser">
+ <property name="name">
+ <cstring>kcfg_Font</cstring>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kfontdialog.h</includehint>
+</includehints>
+</UI>
diff --git a/kjots/confpagemisc.ui b/kjots/confpagemisc.ui
new file mode 100644
index 0000000..ef66e21
--- /dev/null
+++ b/kjots/confpagemisc.ui
@@ -0,0 +1,152 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>confPageMisc</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>confPageMisc</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>289</width>
+ <height>123</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Miscellaneous</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="KIntSpinBox" row="1" column="2">
+ <property name="name">
+ <cstring>kcfg_AutoSaveInterval</cstring>
+ </property>
+ <property name="suffix">
+ <string> minutes</string>
+ </property>
+ <property name="specialValueText">
+ <string>1 minute</string>
+ </property>
+ <property name="maxValue">
+ <number>1440</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This is the number of minutes KJots will wait before automatically saving changes.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>S&amp;ave every:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_AutoSaveInterval</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This is the number of minutes KJots will wait before automatically saving changes.</string>
+ </property>
+ </widget>
+ <spacer row="1" column="3">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="3" column="2">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>kcfg_AutoSave</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Save changes periodically</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>When "Enable autosave" is checked, KJots will automatically save changes made to books at the interval defined below.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>kcfg_Unicode</cstring>
+ </property>
+ <property name="text">
+ <string>Use Unico&amp;de encoding</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>kcfg_AutoSave</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>kcfg_AutoSaveInterval</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_AutoSave</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>textLabel1</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>knuminput.h</includehint>
+</includehints>
+</UI>
diff --git a/kjots/icons/Makefile.am b/kjots/icons/Makefile.am
new file mode 100644
index 0000000..7345ca5
--- /dev/null
+++ b/kjots/icons/Makefile.am
@@ -0,0 +1,6 @@
+
+pics_DATA = filedel.png
+picsdir = $(kde_datadir)/kjots/pics
+
+KDE_ICON = kjots
+
diff --git a/kjots/icons/README b/kjots/icons/README
new file mode 100644
index 0000000..3926e1e
--- /dev/null
+++ b/kjots/icons/README
@@ -0,0 +1,24 @@
+The file jots.xpm is part of the tkgoodstuff package
+copyright (C) 1995-96 by Mark Crimmins ([email protected])
+
+Here is the copyright notice of tkgoodstuff:
+# tkgoodstuff by Mark Crimmins ([email protected])
+# copyright (C) 1995-96, all rights reserved.
+# Void where prohibited. Your mileage may vary.
+
+# Seriously, enjoy my handiwork, but don't sue me if it causes troubles.
+# Also, the University of Michigan has NOTHING WHATEVER to do with this
+# software.
+
+# This program (the tkgoodstuff package) is free software; you can
+# redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software
+# Foundation (version 2 of the License). This program is
+# distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details. For a copy of the GNU General Public
+# License, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
diff --git a/kjots/icons/filedel.png b/kjots/icons/filedel.png
new file mode 100644
index 0000000..6d0d29d
--- /dev/null
+++ b/kjots/icons/filedel.png
Binary files differ
diff --git a/kjots/icons/hi16-app-kjots.png b/kjots/icons/hi16-app-kjots.png
new file mode 100644
index 0000000..5466e25
--- /dev/null
+++ b/kjots/icons/hi16-app-kjots.png
Binary files differ
diff --git a/kjots/icons/hi22-app-kjots.png b/kjots/icons/hi22-app-kjots.png
new file mode 100644
index 0000000..36ce904
--- /dev/null
+++ b/kjots/icons/hi22-app-kjots.png
Binary files differ
diff --git a/kjots/icons/hi32-app-kjots.png b/kjots/icons/hi32-app-kjots.png
new file mode 100644
index 0000000..b2b128d
--- /dev/null
+++ b/kjots/icons/hi32-app-kjots.png
Binary files differ
diff --git a/kjots/icons/hi48-app-kjots.png b/kjots/icons/hi48-app-kjots.png
new file mode 100644
index 0000000..142af59
--- /dev/null
+++ b/kjots/icons/hi48-app-kjots.png
Binary files differ
diff --git a/kjots/icons/hi64-app-kjots.png b/kjots/icons/hi64-app-kjots.png
new file mode 100644
index 0000000..ec0f270
--- /dev/null
+++ b/kjots/icons/hi64-app-kjots.png
Binary files differ
diff --git a/kjots/kjots.kcfg b/kjots/kjots.kcfg
new file mode 100644
index 0000000..4350210
--- /dev/null
+++ b/kjots/kjots.kcfg
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <kcfgfile name="kjotsrc"/>
+ <group name="kjots">
+ <entry name="SplitterSizes" type="IntList">
+ <label>How the main window is divided.</label>
+ </entry>
+ <entry name="CurrentSelection" type="UInt64">
+ <label>The book or page that is currently active.</label>
+ </entry>
+ <entry name="Font" type="Font">
+ <label>The font used to display the contents of books.</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry name="AutoSave" type="Bool">
+ <label>Whether books should be saved automatically.</label>
+ <default>true</default>
+ </entry>
+ <entry name="Unicode" type="Bool">
+ <label>Whether UTF-8 encoding should be forced for saving and loading.</label>
+ <default>false</default>
+ </entry>
+ <entry name="AutoSaveInterval" type="Int">
+ <label>The interval in minutes at which books should be saved automatically.</label>
+ <default>5</default>
+ </entry>
+ <entry name="LastId" type="UInt64">
+ <label>The last ID that was used for a book or page.</label>
+ <default>0</default>
+ </entry>
+ </group>
+</kcfg>
diff --git a/kjots/kjotsbookmarks.cpp b/kjots/kjotsbookmarks.cpp
new file mode 100644
index 0000000..b339a46
--- /dev/null
+++ b/kjots/kjotsbookmarks.cpp
@@ -0,0 +1,51 @@
+//
+// kjotsbookmarks
+//
+// Copyright (C) 1997 Christoph Neerfeld
+// Copyright (C) 2002, 2003 Aaron J. Seigo
+// Copyright (C) 2003 Stanislav Kljuhhin
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "KJotsMain.h"
+#include "kjotsbookmarks.h"
+
+KJotsBookmarks::KJotsBookmarks(KJotsMain* parent, const char* name)
+ : QObject(parent, name),
+ m_kjots(parent)
+{
+}
+
+KJotsBookmarks::~KJotsBookmarks()
+{
+}
+
+void KJotsBookmarks::openBookmarkURL(const QString& page)
+{
+ emit openPage(page);
+}
+
+QString KJotsBookmarks::currentURL() const
+{
+ return m_kjots->currentBookmarkURL();
+}
+
+QString KJotsBookmarks::currentTitle() const
+{
+ return m_kjots->currentBookmarkTitle();
+}
+
+#include "kjotsbookmarks.moc"
diff --git a/kjots/kjotsbookmarks.h b/kjots/kjotsbookmarks.h
new file mode 100644
index 0000000..7cb3144
--- /dev/null
+++ b/kjots/kjotsbookmarks.h
@@ -0,0 +1,51 @@
+//
+// kjotsbookmarks
+//
+// Copyright (C) 1997 Christoph Neerfeld
+// Copyright (C) 2002, 2003 Aaron J. Seigo
+// Copyright (C) 2003 Stanislav Kljuhhin
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef KJOTSBOOKMARKS
+#define KJOTSBOOKMARKS
+
+#include <kbookmarkmanager.h>
+
+class KJotsMain;
+
+class KJotsBookmarks : public QObject, public KBookmarkOwner
+{
+ Q_OBJECT
+
+ public:
+ KJotsBookmarks(KJotsMain* parent = 0, const char* name = 0);
+ ~KJotsBookmarks();
+
+ virtual void openBookmarkURL(const QString& url);
+ virtual QString currentURL() const;
+ QString currentTitle() const;
+
+ signals:
+ void openPage(const QString& page);
+
+ private:
+ KJotsMain* m_kjots;
+};
+
+
+#endif
+/* ex: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab: */
diff --git a/kjots/kjotsedit.cpp b/kjots/kjotsedit.cpp
new file mode 100644
index 0000000..0a61c62
--- /dev/null
+++ b/kjots/kjotsedit.cpp
@@ -0,0 +1,150 @@
+//
+// kjots
+//
+// Copyright (C) 1997 Christoph Neerfeld
+// Copyright (C) 2002, 2003 Aaron J. Seigo
+// Copyright (C) 2003 Stanislav Kljuhhin
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include <qpainter.h>
+#include <qpaintdevicemetrics.h>
+#include <qcursor.h>
+
+#include <kpopupmenu.h>
+#include <keditcl.h>
+#include <klocale.h>
+#include <kopenwith.h>
+#include <kprinter.h>
+
+#include "kjotsedit.h"
+#include "kjotsentry.h"
+
+//----------------------------------------------------------------------
+// MYMULTIEDIT
+//----------------------------------------------------------------------
+KJotsEdit::KJotsEdit (QWidget* parent, const char* name)
+ : KEdit(parent, name),
+ m_entry(0)
+{
+ // no rich text until printing and other such issues are worked out
+ setTextFormat(Qt::PlainText);
+ setWordWrap(QTextEdit::WidgetWidth);
+ setLinkUnderline(true);
+ web_menu = new KPopupMenu(this);;
+ web_menu->insertItem(i18n("Open URL"), this, SLOT(openUrl()) );
+}
+
+KJotsEdit::~KJotsEdit()
+{
+
+}
+
+void KJotsEdit::mousePressEvent( QMouseEvent *e )
+{
+ if(e->button() == RightButton &&
+ hasSelectedText())
+ {
+ KURL url(selectedText());
+
+ if(url.isValid())
+ {
+ web_menu->popup(QCursor::pos());
+ return;
+ }
+ }
+
+ KEdit::mousePressEvent(e);
+}
+
+void KJotsEdit::openUrl()
+{
+ if (hasSelectedText())
+ {
+ KURL url(selectedText());
+ if(url.isValid())
+ {
+ new KRun(url);
+ }
+ }
+}
+
+void KJotsEdit::print(QString title)
+{
+ KPrinter printer;
+ printer.setDocName(title);
+ printer.setFullPage(false);
+ printer.setCreator("KJots");
+
+ if (printer.setup(this))
+ {
+ QFont printFont = font();
+ QPainter painter( &printer );
+ QPaintDeviceMetrics metrics( &printer );
+ int y = 0;
+ int maxWidth = metrics.width();
+ int maxHeight = metrics.height();
+ QString currentParagraph;
+
+ for (int paragraphCount = 0; paragraphCount < paragraphs(); ++paragraphCount )
+ {
+ currentParagraph = text(paragraphCount);
+ QRect r = painter.boundingRect(0, y, maxWidth, maxHeight,
+ QPainter::ExpandTabs | QPainter::WordBreak,
+ currentParagraph);
+
+ if ((y + r.height()) > maxHeight)
+ {
+ printer.newPage();
+ y = 0;
+ }
+
+ painter.drawText(0, y, maxWidth, maxHeight - y,
+ QPainter::ExpandTabs | QPainter::WordBreak,
+ currentParagraph);
+ y += r.height();
+ }
+ painter.end();
+ }
+}
+
+void KJotsEdit::setEntry (KJotsPage *entry)
+{
+ //tell the old entry to take a hike
+ if ( m_entry )
+ {
+ m_entry->setEditor(0);
+ }
+
+ //load up the new entry (assuming there is one)
+ if ( entry )
+ {
+ m_entry = entry;
+ setText(entry->body());
+ removeSelection();
+ repaint();
+ setEnabled(true);
+ setFocus();
+ entry->setEditor(this);
+ } else {
+ clear();
+ }
+
+ m_entry = entry;
+}
+
+#include "kjotsedit.moc"
+/* ex: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab: */
diff --git a/kjots/kjotsedit.h b/kjots/kjotsedit.h
new file mode 100644
index 0000000..cae025c
--- /dev/null
+++ b/kjots/kjotsedit.h
@@ -0,0 +1,54 @@
+//
+// kjots
+//
+// Copyright (C) 1997 Christoph Neerfeld
+// Copyright (C) 2002, 2003 Aaron J. Seigo
+// Copyright (C) 2003 Stanislav Kljuhhin
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef __KJOTSEDIT_H
+#define __KJOTSEDIT_H
+
+#include <keditcl.h>
+class KPopupMenu;
+class KJotsPage;
+
+class KJotsEdit : public KEdit
+{
+ Q_OBJECT
+ public:
+ KJotsEdit (QWidget* parent=0, const char* name=0);
+ ~KJotsEdit ();
+
+ void print(QString title = QString::null);
+ void setEntry(KJotsPage*);
+
+ signals:
+ void findSuccessful();
+
+ protected slots:
+ void openUrl();
+
+ protected:
+ virtual void mousePressEvent (QMouseEvent *e);
+
+ KPopupMenu *web_menu;
+ KJotsPage *m_entry; //!< The entry we are editing. It needs to be kept informed.
+};
+
+#endif // __KJOTSEDIT_H
+/* ex: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab: */
diff --git a/kjots/kjotsentry.cpp b/kjots/kjotsentry.cpp
new file mode 100644
index 0000000..a27b00e
--- /dev/null
+++ b/kjots/kjotsentry.cpp
@@ -0,0 +1,1234 @@
+//
+// kjots
+//
+// Copyright (C) 1997 Christoph Neerfeld
+// Copyright (C) 2002, 2003 Aaron J. Seigo
+// Copyright (C) 2003 Stanislav Kljuhhin
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include <qdir.h>
+#include <qpainter.h>
+#include <qpaintdevicemetrics.h>
+#include <qtextcodec.h>
+#include <qdom.h>
+
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kprogress.h>
+#include <kstandarddirs.h>
+#include <ktempfile.h>
+
+#include <kio/job.h>
+#include <assert.h>
+
+#include "kjotsedit.h"
+#include "KJotsMain.h"
+#include "KJotsSettings.h"
+#include "kjotsentry.h"
+
+// helper functions for HTML output
+QString prepForHTML(QString text)
+{
+ text.replace("<", "&lt;");
+ text.replace(">", "&gt;");
+ text.replace("\n", "<br>");
+ return text;
+}
+
+QString htmlHeader(const QString& title, QTextCodec* codec)
+{
+ QString head = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=";
+ head+=codec->mimeName();
+ head+="\" ><title>" + prepForHTML(title) + "</title></head><body>";
+ return head;
+}
+
+QString htmlFooter()
+{
+ return "</body></html>";
+}
+
+//
+// KJotsEntryBase
+//
+
+KJotsEntryBase::KJotsEntryBase(KListView* parent, QListViewItem* after=0)
+ :KListViewItem(parent,after)
+{
+ m_id = 0;
+ m_saveInProgress = m_dirty = false;
+ m_parent = 0;
+}
+
+KJotsEntryBase::KJotsEntryBase(KListViewItem* parent, QListViewItem* after=0)
+ :KListViewItem(parent,after)
+{
+ m_id = 0;
+ m_saveInProgress = m_dirty = false;
+ m_parent = dynamic_cast<KJotsBook*>(parent);
+}
+
+void KJotsEntryBase::setSubject(const QString& subj)
+{
+ setText(0, subj);
+}
+
+void KJotsEntryBase::setText(int column, const QString& text)
+{
+ if (column == 0 && text.isEmpty())
+ KListViewItem::setText(0, defaultSubject());
+ else
+ KListViewItem::setText(column, text);
+}
+
+/*!
+ \brief Sets a new parent.
+ This is mostly just used during drag-and-drop reordering in the list view.
+ We need to keep track of the previous parent in case the move is invalid.
+*/
+void KJotsEntryBase::resetParent()
+{
+ m_parent = dynamic_cast<KJotsBook*>(QListViewItem::parent());
+}
+
+/*!
+* \brief Set the ID number.
+* \param id The ID to set, or 0 to pick a fresh one.
+*
+* Set ourselves to a particular ID number, or pick a new one. The lastId used is
+* stored in the settings. Now in theory it will eventually wrap, and may collide
+* with preexisting IDs. Seeing as how we are using an unsigned long long, I am
+* comfortable with the amount of time we have to worry about this.
+*/
+void KJotsEntryBase::setId(Q_UINT64 id)
+{
+ //Find an unused id...
+ if ( id == 0 )
+ {
+ Q_UINT64 lastId = KJotsSettings::lastId();
+
+ //TODO: In theory, we could wrap. The universe may end beforehand tho.
+ id = ++lastId;
+ if ( id == 0 ) id = ++lastId; //*IF* by some chance we do wrap, this will prevent bad things.
+ KJotsSettings::setLastId(id);
+ }
+
+ m_id = id;
+ return;
+}
+
+/*!
+ \brief Performs functions necessary to save the entry to a KJots file.
+ This function should ONLY be called when saving the file, as it performs
+ other functions than generating XML.
+*/
+void KJotsEntryBase::generateXml( QDomDocument &doc, QDomElement &parent )
+{
+ QDomElement title = doc.createElement( "Title" );
+ title.appendChild( doc.createTextNode( subject() ));
+ parent.appendChild( title );
+
+ QDomElement id = doc.createElement( "ID" );
+ QString id_string;
+ id_string.setNum(m_id);
+ id.appendChild( doc.createTextNode(id_string) );
+ parent.appendChild( id );
+
+ setDirty( false );
+ return;
+}
+
+/*!
+ Parses through XML data for settings inherent to the base class.
+*/
+void KJotsEntryBase::parseXml( QDomElement &e )
+{
+ if ( !e.isNull() )
+ {
+ if ( e.tagName() == "Title" )
+ {
+ setSubject(e.text());
+ }
+ else
+ if ( e.tagName() == "ID" )
+ {
+ setId(e.text().toULongLong());
+ }
+ }
+
+ return;
+}
+
+/*!
+ \brief Draws the Title box when printing.
+ This is a helper function for the derived classes. Code consolidation==the good.
+*/
+int KJotsEntryBase::printTitleBox(QString title, KPrinter& printer, QPainter& painter, int y)
+{
+ QPaintDeviceMetrics metrics( &printer );
+ int maxWidth = metrics.width();
+ int maxHeight = metrics.height();
+
+ QRect r = painter.boundingRect(0, y,
+ maxWidth, maxHeight,
+ QPainter::ExpandTabs | QPainter::WordBreak | QPainter::AlignHCenter,
+ title);
+ y += 10;
+
+ if ((y + r.height()) > maxHeight)
+ {
+ printer.newPage();
+ y = 0;
+ }
+ else
+ {
+ r.moveBy(0, 10);
+ }
+
+ r.setLeft(0);
+ r.setRight(maxWidth);
+ painter.drawRect(r);
+ painter.drawText(0, y, maxWidth, maxHeight - y,
+ QPainter::ExpandTabs | QPainter::WordBreak | QPainter::AlignHCenter,
+ title);
+ y += r.height() + 15;
+
+ return y;
+}
+
+//
+// KJotsBook
+//
+
+KJotsBook::KJotsBook(KListView* parent, QListViewItem* after)
+ : KJotsEntryBase(parent, after)
+{
+ init();
+}
+
+KJotsBook::KJotsBook(KListViewItem* parent, QListViewItem* after)
+ : KJotsEntryBase(parent, after)
+{
+ init();
+}
+
+KJotsBook::~KJotsBook()
+{
+}
+
+/*!
+ \brief Initialize a KJotsBook object.
+
+ This function is used for code consolidation. Otherwise, you'de have to change these
+ things in both constructors.
+*/
+void KJotsBook::init()
+{
+ m_isBook = true;
+ m_open = false;
+ m_saveProgressDialog = 0;
+ setExpandable(true);
+ setPixmap(0, kapp->iconLoader()->loadIcon(QString("contents"),KIcon::Small));
+}
+
+/*!
+ \brief Is this a KJots file?
+ \param filename Filename to check.
+
+ This function does a cursory check to see if this looks like it is a KJots file.
+ It's a little too quick and dirty for my taste, but seems to work OK.
+*/
+bool KJotsBook::isBookFile(const QString& filename)
+{
+ QFile folder(filename);
+ bool test = false;
+
+ if ( folder.exists() )
+ {
+ if ( folder.open(IO_ReadWrite) )
+ {
+ QTextStream st(static_cast<QIODevice*>(&folder));
+ st.setEncoding( KJotsSettings::unicode() ? QTextStream::UnicodeUTF8 : QTextStream::Locale );
+ QString buf = st.readLine().stripWhiteSpace();
+
+ //Check for new-style book. Not very pretty, but it is faster than loading the DOM.
+ if (buf == "<!DOCTYPE KJots>")
+ {
+ test=true;
+ }
+ else
+ //Check for old-style book. See KJotsBook::loadOldBook()
+ if (buf.left(9) == "\\NewEntry")
+ {
+ test=true;
+ }
+
+ }
+ }
+
+ return test;
+}
+
+/*!
+ \brief Reads a book in from a disk file.
+ This function is only called for root-level books.
+*/
+bool KJotsBook::openBook(const QString& filename)
+{
+ if ( !m_open ) //sanity check
+ {
+ listView()->setUpdatesEnabled(false);
+ m_fileName = filename;
+
+ if ( m_fileName.isEmpty() ) //new books names are empty.
+ {
+ addPage();
+ m_open = true;
+ } else {
+ QFile file(m_fileName);
+
+ if ( file.exists() && file.open(IO_ReadWrite) ) //TODO: Implement read-only mode?
+ {
+ QTextStream st(static_cast<QIODevice*>(&file));
+ st.setEncoding( KJotsSettings::unicode() ? QTextStream::UnicodeUTF8 : QTextStream::Locale );
+ QString data = st.read();
+
+ QDomDocument doc( "KJots" );
+ if ( doc.setContent( data ) )
+ {
+ QDomElement docElem = doc.documentElement();
+
+ if ( docElem.tagName() == "KJots" )
+ {
+ QDomNode n = docElem.firstChild();
+ while( !n.isNull() )
+ {
+ QDomElement e = n.toElement(); // try to convert the node to an element.
+ if( !e.isNull() && e.tagName() == "KJotsBook" )
+ {
+ parseXml(e);
+ }
+ n = n.nextSibling();
+ }
+ }
+
+ } else {
+ //Woah. Something didn't work right. Maybe this is an old file?
+ file.reset();
+ if ( loadOldBook(file) )
+ {
+ QFileInfo fi( file );
+ setSubject(fi.fileName());
+ }
+ }
+ }
+
+ if ( !childCount() ) //sanity check
+ {
+ //We should NOT be here. That must not have been a book file, or it is damaged.
+ //To make things happy-happy, we just create a blank page and continue.
+ //TODO: Add an information message? Make a translater work for something so unlikely?
+ addPage();
+ }
+
+ m_open = true;
+
+ // Support legacy files. Can be removed at some point. CREATION DATE: 2005/06/04
+ if ( !m_fileName.isEmpty() && !m_fileName.endsWith(".book") )
+ {
+ //some old books have incorrect names. So we save a new copy, then kill the old file
+ m_fileName = QString::null; //trick ourselves into thinking we're a new book
+ saveBook();
+ file.remove();
+ }
+ }
+
+ listView()->setUpdatesEnabled(true);
+
+ // Support legacy files. Can be removed at some point. CREATION DATE: 2005/06/07
+ if ( m_open && !id() )
+ {
+ //This book (and its pages) need new IDs!
+ setId(0);
+
+ KJotsPage *page = dynamic_cast<KJotsPage*>(firstChild());
+ while ( page )
+ {
+ page->setId(0); //TODO: Make setId() a protected function if this legacy code is removed.
+ page = dynamic_cast<KJotsPage*>(page->nextSibling());
+ }
+ }
+ }
+
+ return m_open;
+}
+
+/*!
+ \brief Load an old-style book file.
+
+ This is a function for files made from older KJots versions. It could probably be removed
+ at some point in the future. CREATION DATE: 2005/05/30
+*/
+bool KJotsBook::loadOldBook(QFile &file)
+{
+ QTextStream st(static_cast<QIODevice*>(&file));
+ st.setEncoding( KJotsSettings::unicode() ? QTextStream::UnicodeUTF8 : QTextStream::Locale );
+ QString buf = st.readLine();
+
+ if (buf.left(9) != "\\NewEntry")
+ {
+ addPage();
+ return false;
+ }
+
+ KJotsPage *entry = 0;
+ QString body;
+
+ bool quit=false;
+
+ while (1)
+ {
+ if (buf.left(9) == "\\NewEntry")
+ {
+ if (entry)
+ {
+ entry->setBody(body);
+ }
+
+ body = QString::null;
+ QString title = buf.mid(10, buf.length());
+
+ // now catch the page id
+ buf = st.readLine();
+ if (buf.left(3) == "\\ID")
+ {
+ buf = st.readLine();
+ }
+
+ entry = new KJotsPage(this, entry);
+ entry->setSubject(title);
+ }
+
+ int pos = 0;
+
+ while ((pos = buf.find('\\',pos)) != -1)
+ if (buf[++pos] == '\\')
+ buf.remove(pos, 1 );
+
+ body.append( buf + "\n");
+
+ if (quit)
+ break;
+
+ buf = st.readLine();
+
+ quit = st.eof();
+ }
+
+ entry->setBody(body);
+ return true;
+}
+
+/*!
+ \brief Saves this book and everything in it to the data directory.
+*/
+void KJotsBook::saveBook(void)
+{
+ if (!m_open) //sanity check
+ return;
+
+ // Are we a new book?
+ if ( m_fileName.isEmpty() )
+ {
+ KTempFile temp(locateLocal("appdata",""), ".book", 0644);
+ m_fileName = temp.name();
+ }
+
+ QFile file(m_fileName);
+ if (file.open(IO_WriteOnly | IO_Truncate))
+ {
+ QDomDocument doc("KJots");
+ QDomElement root = doc.createElement( "KJots" );
+ doc.appendChild( root );
+
+ this->generateXml( doc, root ); //recursive
+
+ QTextStream st((QIODevice *) &file);
+ st.setEncoding( KJotsSettings::unicode() ? QTextStream::UnicodeUTF8 : QTextStream::Locale );
+ st << doc.toString();
+
+ file.close();
+ }
+
+}
+
+/*!
+ \brief Deletes a book by removing the data file.
+ This does not affect the list display, and can be called for reasons other than
+ choosing to delete an entry from the list. If you want the object to dissappear
+ from the list, then you have to delete it.
+*/
+void KJotsBook::deleteBook()
+{
+ QFile::remove(m_fileName);
+ m_fileName = QString::null;
+}
+
+void KJotsBook::rename()
+{
+ bool ok;
+ QString name = KInputDialog::getText(i18n( "Rename Book" ),
+ i18n( "Book name:" ),
+ subject(), &ok, listView());
+ if (ok)
+ {
+ setSubject(name);
+
+ KJotsMain* m = dynamic_cast<KJotsMain*>(kapp->mainWidget());
+
+ if (m)
+ m->updateCaption();
+
+ setDirty(true);
+ }
+}
+
+/*!
+ \brief Initiated when the user chooses to save this to a file.
+ This function gets everything ready to go to save to the disk.
+*/
+void KJotsBook::saveToFile(KURL url, bool plainText, const QString& encoding)
+{
+ if (url.isEmpty() || m_saveInProgress)
+ return;
+
+ m_saveToPlainText = plainText;
+ m_saveEncoding = QTextCodec::codecForName(encoding.ascii());
+ KIO::TransferJob* job = KIO::put(url, -1, true, false, false);
+
+ if (!job)
+ {
+ return;
+ }
+
+ //NOTE: The current implementation does not need the progress dialog, but further
+ //revisions will likely use it. I don't want to make the translators add, remove,
+ //and re-add translations, so I'm just keeping this here for now.
+ m_saveProgressDialog = new KProgressDialog(listView(), "bookSaveInProgress",
+ i18n("Saving %1").arg(subject()),
+ i18n("Saving the contents of %1 to %2")
+ .arg(subject(), url.prettyURL()),
+ true);
+
+ m_saveProgressDialog->progressBar()->setTotalSteps(1);
+ m_saveProgressDialog->showCancelButton(false);
+ m_saveProgressDialog->setAutoClose(true);
+
+ connect(job, SIGNAL(dataReq(KIO::Job*, QByteArray&)), SLOT(saveDataReq(KIO::Job*, QByteArray&)));
+ connect(job, SIGNAL(result( KIO::Job *)), SLOT(slotSaveResult( KIO::Job *)));
+
+ m_saveInProgress = true;
+}
+
+/*!
+ \brief Pumps out data when saving to a file.
+ This function pumps out page data during a disk save.
+*/
+void KJotsBook::saveDataReq(KIO::Job* /* job */, QByteArray& data)
+{
+ if (!m_saveInProgress) return; //sanity check
+
+ QTextStream stream(data, IO_WriteOnly);
+ stream.setCodec(m_saveEncoding);
+
+ if (!m_saveToPlainText)
+ {
+ stream << htmlHeader(subject(), m_saveEncoding);
+ stream << generateHtml(this, true);
+ stream << htmlFooter();
+ } else {
+ stream << generateText();
+ }
+
+ m_saveInProgress = false;
+}
+
+/*!
+ \brief Completes a disk save.
+ This function is called after a disk save. The disk save may or may
+ not have completed normally.
+*/
+void KJotsBook::slotSaveResult(KIO::Job *)
+{
+ m_saveInProgress = false;
+ delete m_saveProgressDialog;
+ m_saveProgressDialog = 0;
+ /* if (job->error() != 0) {} */
+}
+
+/*!
+ \brief Add a new page to the end of this book.
+*/
+KJotsPage* KJotsBook::addPage()
+{
+ QListViewItem *after = 0;
+
+ // append new pages
+ QListViewItem* tmp = firstChild();
+ while (tmp)
+ {
+ after = tmp;
+ tmp = tmp->nextSibling();
+ }
+
+ KJotsPage *page = new KJotsPage(this, after);
+ page->initNewPage();
+ return page;
+}
+
+/*!
+ \brief Called when the user wants to print the book.
+*/
+void KJotsBook::print(QFont& defaultFont)
+{
+ KPrinter printer;
+ printer.setDocName(subject());
+ printer.setFullPage(false);
+ printer.setCreator("KJots");
+
+ if (!printer.setup(listView(), i18n("Print: %1").arg(subject())))
+ {
+ return;
+ }
+
+ QPainter painter(&printer);
+ painter.setFont(defaultFont);
+ print(printer, painter, 0);
+
+ painter.end();
+}
+
+/*!
+ \brief Prints this book.
+*/
+int KJotsBook::print(KPrinter& printer, QPainter& painter, int y)
+{
+ y = printTitleBox(subject(), printer, painter, y);
+
+ KJotsEntryBase* entry = dynamic_cast<KJotsEntryBase*>(firstChild());
+ while (entry)
+ {
+ y = entry->print(printer, painter, y);
+ entry = dynamic_cast<KJotsEntryBase*>(entry->nextSibling());
+ }
+
+ return y;
+}
+
+QString KJotsBook::defaultSubject()
+{
+ return i18n("Untitled Book");
+}
+
+/*!
+ \brief Does this book need to be saved?
+ This function recursively checks itself, and all books and pages it owns to
+ see if any changes have been made.
+*/
+bool KJotsBook::isDirty()
+{
+ //Am I dirty?
+ if ( KJotsEntryBase::isDirty() ) return true;
+
+ //Check all children to see if any of them are dirty
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(firstChild());
+ while ( entry )
+ {
+ if ( entry->isDirty() ) return true;
+ entry = dynamic_cast<KJotsEntryBase*>(entry->nextSibling());
+ }
+
+ return false;
+}
+
+/*!
+ \brief Creates XML code and performs necessary tasks to save file.
+ This function should ONLY be called when saving the file.
+*/
+void KJotsBook::generateXml( QDomDocument &doc, QDomElement &parent )
+{
+ QDomElement book = doc.createElement( "KJotsBook" );
+ parent.appendChild( book );
+
+ KJotsEntryBase::generateXml(doc, book); //let the base class save important stuff
+
+ QDomElement open = doc.createElement( "Open" );
+ open.appendChild( this->isOpen() ? doc.createTextNode("1") : doc.createTextNode("0") );
+ book.appendChild( open );
+
+ KJotsEntryBase* entry = dynamic_cast<KJotsEntryBase*>(firstChild());
+ while ( entry )
+ {
+ entry->generateXml( doc, book );
+ entry = dynamic_cast<KJotsEntryBase*>(entry->nextSibling());
+ }
+
+ if ( !m_fileName.isEmpty() && QListViewItem::parent() )
+ {
+ //Hmmmm... We were originally loaded from a file, but now we have a parent, so
+ //we must have been moved into another tree. Remove the old file now that we
+ //have saved ourselves into the new tree.
+ deleteBook();
+ }
+
+ return;
+}
+
+/*!
+ Parses through XML code from a file.
+*/
+void KJotsBook::parseXml( QDomElement &me )
+{
+ KJotsEntryBase *lastEntry = 0; //keep track of the last entry inserted for speed
+
+ if ( me.tagName() == "KJotsBook" )
+ {
+ QDomNode n = me.firstChild();
+ while( !n.isNull() )
+ {
+ QDomElement e = n.toElement(); // try to convert the node to an element.
+ if ( !e.isNull() )
+ {
+ if ( e.tagName() == "KJotsPage" )
+ {
+ KJotsPage *page = new KJotsPage(this, lastEntry);
+ page->parseXml(e);
+ lastEntry=page;
+ }
+ else
+ if ( e.tagName() == "KJotsBook" )
+ {
+ KJotsBook *book = new KJotsBook(this, lastEntry);
+ book->parseXml(e);
+ lastEntry=book;
+ }
+ else
+ if ( e.tagName() == "Open" )
+ {
+ if ( e.text() == "1" )
+ {
+ this->setOpen(true);
+ }
+ }
+ else
+ {
+ //What was this? Send it to the base class and see if it can figure it out.
+ KJotsEntryBase::parseXml(e);
+ }
+ }
+ n = n.nextSibling();
+ }
+ }
+
+ return;
+}
+
+/*!
+ \brief Returns an HTML Table of contents for this book.
+ This is a helper function for generateHtml().
+*/
+QString KJotsBook::getToc()
+{
+ QString toc;
+
+ toc += "<ul>";
+
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(firstChild());
+ while ( entry ) {
+ QString htmlSubject = prepForHTML(entry->subject());
+ toc += QString("<li><a href=\"#%1\">").arg(entry->id()) + htmlSubject + "</a></li>";
+
+ KJotsBook *book = dynamic_cast<KJotsBook*>(entry);
+ if ( book ) toc += book->getToc();
+
+ entry = dynamic_cast<KJotsEntryBase*>(entry->nextSibling());
+ }
+
+ toc += "</ul>";
+ return toc;
+}
+
+/*!
+ \brief Returns HTML for the read-only "book" view.
+ \param top Pointer to the "starting point" of this tree.
+ \param diskMode Files saved to disk have a slightly different format.
+*/
+QString KJotsBook::generateHtml( KJotsEntryBase* top, bool diskMode )
+{
+ QString toc, body;
+ QString htmlTitle = prepForHTML(subject());
+
+ if ( top == this )
+ {
+ toc = QString("<h1><a name=\"%1\">%2</a></h1>").arg(id()).arg(htmlTitle);
+ } else {
+ if ( diskMode )
+ {
+ toc = QString("<h2><a name=\"%1\">%2</a></h2>").arg(id()).arg(htmlTitle);
+ } else {
+ toc = QString("<h2><a name=\"%1\" href=\"%2\">%3</a></h2>").arg(id()).arg(id()).arg(htmlTitle);
+ }
+ }
+
+ toc += "<h3>" + i18n("Table of Contents") + "</h3>";
+ toc += getToc();
+ toc += "<hr>";
+
+ // Do the body text of the entries.
+ KJotsEntryBase* entry = dynamic_cast<KJotsEntryBase*>(firstChild());
+ while ( entry )
+ {
+ body += entry->generateHtml(top, diskMode);
+ entry = dynamic_cast<KJotsEntryBase*>(entry->nextSibling());
+ }
+
+ return toc + body;
+}
+
+/*!
+ \brief Returns Text when saving to a file.
+
+ This functions output moderately formatted text when the user chooses to save as
+ a text file.
+*/
+QString KJotsBook::generateText( void )
+{
+ QString out;
+
+ //Print Fancy Text header
+ QString line, buf;
+ line.fill('#', subject().length() + 2);
+ line += "\n";
+ out = line + QString("# ") + subject() + QString("\n") + line;
+
+ KJotsEntryBase* entry = dynamic_cast<KJotsEntryBase*>(firstChild());
+ while ( entry )
+ {
+ out += entry->generateText();
+ entry = dynamic_cast<KJotsEntryBase*>(entry->nextSibling());
+ }
+
+ out += "\n";
+ return out;
+}
+
+//
+// KJotsPage
+//
+
+KJotsPage::KJotsPage(KJotsBook* parent, QListViewItem *after)
+ : KJotsEntryBase(parent,after),
+ m_editor(0)
+{
+ m_isBook = false;
+ m_paraPos = m_indexPos = 0;
+ setPixmap(0, kapp->iconLoader()->loadIcon(QString("edit"), KIcon::Small));
+}
+
+KJotsPage::~KJotsPage()
+{
+ if ( m_editor )
+ {
+ //Well now, this isn't good. We're going bye-bye but the editor
+ //still thinks we're here. Set ourselves to 0 (IMPORTANT!!) and
+ //then clear the editor.
+ KJotsEdit *temp = m_editor;
+ m_editor=0;
+ temp->setEntry(0);
+ }
+}
+
+/*!
+ \brief Sets up info for a new page.
+
+ This should be called on brand new pages.
+*/
+void KJotsPage::initNewPage(void)
+{
+ setId(0);
+ setSubject(defaultSubject());
+}
+
+/*!
+ \brief Return the text of this page.
+*/
+QString KJotsPage::body()
+{
+ //if we're being edited we want the current text, not whatever we saved before.
+ if ( m_editor && m_editor->edited() )
+ {
+ m_text = m_editor->text();
+ m_editor->setEdited(false);
+ setDirty(true);
+ }
+
+ return m_text;
+}
+
+/*!
+ \brief Sets the text of this page.
+*/
+void KJotsPage::setBody(const QString& text)
+{
+ assert ( !m_editor ); //m_editor should *never* be set.
+ m_text = text;
+}
+
+void KJotsPage::rename()
+{
+ bool ok;
+
+ QString name = KInputDialog::getText(i18n( "Rename Page" ),
+ i18n( "Page title:" ),
+ subject(), &ok, listView() );
+
+ if (ok)
+ {
+ setSubject(name);
+
+ KJotsMain* m = dynamic_cast<KJotsMain*>(kapp->mainWidget());
+
+ if (m)
+ m->updateCaption();
+
+ setDirty(true);
+ }
+}
+
+/*!
+ \brief Initiated when the user chooses to save this to a file.
+ This function gets everything ready to go to save to the disk.
+*/
+void KJotsPage::saveToFile(KURL url, bool plainText, const QString& encoding)
+{
+ if (url.isEmpty() || m_saveInProgress)
+ return;
+
+ m_saveToPlainText = plainText;
+ m_saveEncoding = QTextCodec::codecForName(encoding.ascii());
+ KIO::TransferJob* job = KIO::put(url, -1, true, false, false);
+ if (!job)
+ {
+ return;
+ }
+
+ connect(job, SIGNAL(dataReq(KIO::Job*, QByteArray&)), SLOT(saveDataReq(KIO::Job*, QByteArray&)));
+ connect(job, SIGNAL(result( KIO::Job *)), SLOT(slotSaveResult( KIO::Job *)));
+ m_saveInProgress = true;
+}
+
+/*!
+ \brief Pumps out data when saving to a file.
+ This function pumps out page data during a disk save.
+
+ \todo This should be augmented to cycle in case of REALLY long pages.
+*/
+void KJotsPage::saveDataReq(KIO::Job* /* job */, QByteArray& data)
+{
+ if (!m_saveInProgress) return; //sanity check
+
+ QTextStream stream(data, IO_WriteOnly);
+ stream.setCodec(m_saveEncoding);
+
+ if ( !m_saveToPlainText )
+ {
+ stream << htmlHeader(subject(), m_saveEncoding);
+ stream << generateHtml(this, true);
+ stream << htmlFooter();
+ } else {
+ stream << generateText();
+ }
+
+ m_saveInProgress = false;
+}
+
+/*!
+ \brief Completes a disk save.
+ This function is called after a disk save. The disk save may or may
+ not have completed normally.
+*/
+void KJotsPage::slotSaveResult(KIO::Job *)
+{
+ m_saveInProgress = false;
+ /* if (job->error() != 0) {} */
+}
+
+void KJotsPage::print(QFont& defaultFont)
+{
+ KJotsEntryBase* book = dynamic_cast<KJotsEntryBase*>(KListViewItem::parent());
+
+ QString docName = book->subject();
+ if (!subject().isNull())
+ {
+ docName += ": " + subject();
+ }
+
+ KPrinter printer;
+ printer.setDocName(docName);
+ printer.setFullPage(false);
+ printer.setCreator("KJots");
+
+ if (printer.setup(listView(), i18n("Print: %1").arg(docName)))
+ {
+ QPainter painter( &printer );
+ painter.setFont(defaultFont);
+ print(printer, painter, 0);
+ painter.end();
+ }
+}
+
+/*!
+ \brief Prints this page.
+*/
+int KJotsPage::print(KPrinter& printer, QPainter& painter, int y)
+{
+ QPaintDeviceMetrics metrics( &printer );
+ int maxWidth = metrics.width();
+ int maxHeight = metrics.height();
+ //TODO: Is it really necessary to copy the entire body when printing?
+ QStringList paragraphs = QStringList::split(QChar('\n'), body(), true);
+
+ y = printTitleBox(subject(), printer, painter, y);
+
+ for (QStringList::iterator para = paragraphs.begin();
+ para != paragraphs.end();
+ ++para)
+ {
+ //Watch for blank lines inserted as spacers.
+ if ( (*para).isNull() ) *para = " ";
+
+ QRect r = painter.boundingRect(0, y,
+ maxWidth, maxHeight,
+ QPainter::ExpandTabs | QPainter::WordBreak,
+ *para);
+
+ if ((y + r.height()) > maxHeight)
+ {
+ printer.newPage();
+ y = 0;
+ }
+
+ painter.drawText(0, y, maxWidth, maxHeight - y,
+ QPainter::ExpandTabs | QPainter::WordBreak,
+ *para);
+ y += r.height();
+ }
+
+ return y;
+}
+
+/*!
+ \brief Get the default title of this page.
+ \note This is only used by initNewPage(); it could probably be removed.
+*/
+QString KJotsPage::defaultSubject()
+{
+ int page = 0;
+
+ if ( parentBook() )
+ {
+ //We can't use childCount() here because it will count books, too.
+ KJotsEntryBase *entry = dynamic_cast<KJotsEntryBase*>(parentBook()->firstChild());
+ while ( entry )
+ {
+ if ( entry->isPage() ) ++page;
+ entry = dynamic_cast<KJotsEntryBase*>(entry->nextSibling());
+ }
+ } else {
+ //We should never be here.
+ page = 1;
+ }
+
+ return i18n("Page %1").arg(page);
+}
+
+/*!
+ \brief Tells this page that it has been loaded into the edit window.
+*/
+void KJotsPage::setEditor( KJotsEdit *editor )
+{
+ //out with the old...
+ if ( m_editor )
+ {
+ m_editor->getCursorPosition(&m_paraPos, &m_indexPos);
+
+ if ( m_editor->edited() )
+ {
+ m_text = m_editor->text();
+ setDirty(true);
+ }
+ }
+
+ m_editor = editor;
+
+ //and in with the new
+ if ( m_editor )
+ {
+ m_editor->setEdited(false);
+ m_editor->setCursorPosition(m_paraPos, m_indexPos);
+ }
+
+ return;
+}
+
+/*!
+ \brief Has the data in this page been changed?
+ We first check the editor status, if we are being edited. Then we let
+ the base class handle things for us.
+*/
+bool KJotsPage::isDirty()
+{
+ if ( m_editor && m_editor->edited() )
+ {
+ setDirty(true);
+ }
+
+ return KJotsEntryBase::isDirty();
+}
+
+/*!
+ \brief Creates XML code and performs necessary tasks to save file.
+ This function should ONLY be called when saving the file.
+*/void KJotsPage::generateXml( QDomDocument &doc, QDomElement &parent )
+{
+ QDomElement page = doc.createElement( "KJotsPage" );
+ parent.appendChild( page );
+
+ KJotsEntryBase::generateXml(doc, page); //let the base class save important stuff
+
+ QDomElement text = doc.createElement( "Text" );
+ QString saveText = body();
+ if ( saveText.contains("]]>") ) {
+ saveText.replace("]]>","]]&gt;");
+ text.setAttribute("fixed", "1");
+ }
+ text.appendChild( doc.createCDATASection( saveText ));
+ page.appendChild( text );
+
+ return;
+}
+
+/*!
+ Parses through XML code from a file.
+*/
+void KJotsPage::parseXml( QDomElement &me )
+{
+ if ( me.tagName() == "KJotsPage" )
+ {
+ QDomNode n = me.firstChild();
+ while( !n.isNull() )
+ {
+ QDomElement e = n.toElement(); // try to convert the node to an element.
+ if ( !e.isNull() )
+ {
+ if ( e.tagName() == "Text" )
+ {
+ QString bodyText = e.text();
+ if ( e.hasAttribute("fixed") )
+ {
+ bodyText.replace("]]&gt;", "]]>");
+ }
+ setBody(bodyText);
+ }
+ else
+ {
+ //What was this? Send it to the base class and see if it can figure it out.
+ KJotsEntryBase::parseXml(e);
+ }
+ }
+ n = n.nextSibling();
+ }
+ }
+
+ return;
+}
+
+/*!
+ \brief Returns HTML for the read-only "book" overview.
+ \param top This tells us that we are the toplevel.
+ \param diskMode Files saved to disk have a slightly different format.
+*/
+QString KJotsPage::generateHtml( KJotsEntryBase *top, bool diskMode )
+{
+ QString html;
+ QString htmlSubject = prepForHTML(subject());
+
+ if ( top == this || diskMode ) {
+ html += QString("<h3><a name=\"%1\">%2</a></h3>").arg(id()).arg(htmlSubject);
+ } else {
+ html += QString("<h3><a name=\"%1\" href=\"%2\">%3</a></h3>").arg(id()).arg(id()).arg(htmlSubject);
+ }
+ html += prepForHTML(body());
+
+ html += "<br><table border=1><tr>";
+ html += QString("<td><a href=\"#%1\">%2</a></td>").arg(id()).arg(subject());
+
+ if ( top != this )
+ {
+ KJotsBook *parent = parentBook();
+ while ( parent )
+ {
+ html += QString("<td><a href=\"#%1\">%2</a></td>").arg(parent->id()).arg(parent->subject());
+ if ( parent == top ) break;
+ parent = parent->parentBook();
+ }
+ }
+ html += QString("</tr></table>");
+
+ if ( top != this ) html += "<hr>";
+ return html;
+}
+
+/*!
+ \brief Returns Text when saving to a file.
+ \param top This is a hint to specify if this book is the "starting point" or not.
+
+ This functions output moderately formatted text when the user chooses to save as
+ a text file.
+*/
+QString KJotsPage::generateText( void )
+{
+ QString out;
+
+ //Print Fancy Text header
+ QString line, buf;
+ line.fill('#', subject().length() + 2);
+ line += "\n";
+ out = line + QString("# ") + subject() + QString("\n") + line;
+
+ out += body();
+
+ out += "\n";
+ return out;
+}
+
+/* ex: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab: */
+
+#include "kjotsentry.moc"
diff --git a/kjots/kjotsentry.h b/kjots/kjotsentry.h
new file mode 100644
index 0000000..a16d176
--- /dev/null
+++ b/kjots/kjotsentry.h
@@ -0,0 +1,179 @@
+//
+// kjots
+//
+// Copyright (C) 1997 Christoph Neerfeld
+// Copyright (C) 2002, 2003 Aaron J. Seigo
+// Copyright (C) 2003 Stanislav Kljuhhin
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef __KJOTSENTRY_H
+#define __KJOTSENTRY_H
+
+#include <klistview.h>
+#include <kprinter.h>
+
+//
+// class KJotsEntryBase
+//
+
+class KURL;
+class KJotsPage;
+class KProgressDialog;
+class KJotsEdit;
+class QTextCodec;
+class QDomDocument;
+class QDomElement;
+class QFile;
+
+class KJotsBook;
+
+namespace KIO
+{
+ class Job;
+}
+
+class KJotsEntryBase : public QObject, public KListViewItem
+{
+ Q_OBJECT
+ public:
+ KJotsEntryBase(KListView*, QListViewItem*);
+ KJotsEntryBase(KListViewItem*, QListViewItem*);
+
+ public:
+ virtual void setSubject(const QString&);
+ QString subject() { return text(0); }
+ void setText(int,const QString&);
+ virtual void saveToFile(KURL, bool plainText, const QString& encoding) = 0;
+ virtual void print(QFont& defaultFont) = 0;
+ virtual int print(KPrinter&, QPainter&, int) = 0;
+ virtual QString defaultSubject() = 0; //!< "subject" is the caption name
+ virtual void rename() = 0;
+ virtual void generateXml( QDomDocument&, QDomElement& );
+ virtual void parseXml( QDomElement& );
+ virtual QString generateHtml( KJotsEntryBase*, bool ) = 0;
+ virtual QString generateText( void ) = 0;
+
+ void setDirty(bool d) { m_dirty = d; } //!< Toggles the dirty flag.
+ virtual bool isDirty() { return m_dirty; }; //!< Accessor for dirty flag.
+
+ Q_UINT64 id() { return m_id; }
+ void setId(Q_UINT64);
+
+ KJotsBook *parentBook() { return m_parent; }
+ void resetParent();
+
+ bool isBook() const { return m_isBook; }
+ bool isPage() const { return !m_isBook; }
+
+ protected:
+ int printTitleBox(QString, KPrinter&, QPainter&, int);
+
+ bool m_saveInProgress; //!< Toggled during a manual disk save.
+ bool m_isBook; //!< used for speed and code clarity.
+
+ private:
+ Q_UINT64 m_id; //!< unique ID for this entry
+ bool m_dirty; //!< Set when this entry has been changed.
+ KJotsBook *m_parent; //!< used during drag-n-drop moving
+};
+
+//
+// class KjotsBook
+//
+
+class KJotsBook : public KJotsEntryBase
+{
+ Q_OBJECT
+ public:
+ KJotsBook(KListView*, QListViewItem* after = 0);
+ KJotsBook(KListViewItem*, QListViewItem* after = 0);
+ ~KJotsBook();
+
+ static bool isBookFile(const QString& book);
+ bool openBook(const QString&);
+ void saveBook();
+ void deleteBook();
+ void rename();
+ void saveToFile(KURL, bool plainText, const QString& encoding);
+ KJotsPage* addPage(); //!< Add a new page to this book.
+ void print(QFont& defaultFont);
+ int print(KPrinter&, QPainter&, int);
+ bool isDirty();
+ QString defaultSubject();
+ void generateXml( QDomDocument&, QDomElement& );
+ void parseXml( QDomElement& );
+ QString generateHtml( KJotsEntryBase*, bool );
+ QString generateText( void );
+
+ protected slots:
+ void saveDataReq(KIO::Job* job, QByteArray& data);
+ void slotSaveResult(KIO::Job*);
+
+ private:
+ QString getToc();
+ bool loadOldBook(QFile &);
+ void init();
+
+ bool m_open;
+ QString m_fileName;
+ bool m_saveToPlainText;
+ QTextCodec* m_saveEncoding;
+ KProgressDialog* m_saveProgressDialog;
+};
+
+//
+// class KJotsPage
+//
+class KJotsPage : public KJotsEntryBase
+{
+ Q_OBJECT
+ public:
+ KJotsPage(KJotsBook* parent, QListViewItem* after = 0);
+ ~KJotsPage();
+
+ public:
+ QString body();
+ void setBody(const QString&);
+ void saveToFile(KURL, bool plainText, const QString& encoding);
+ void print(QFont& defaultFont);
+ int print(KPrinter&, QPainter&, int);
+ QString defaultSubject();
+ void rename();
+
+ void setEditor(KJotsEdit*);
+ bool isDirty();
+ void generateXml( QDomDocument&, QDomElement& );
+ void parseXml( QDomElement& );
+ void initNewPage(void);
+ QString generateHtml( KJotsEntryBase*, bool );
+ QString generateText( void );
+
+ protected slots:
+ void saveDataReq(KIO::Job* job, QByteArray& data);
+ void slotSaveResult(KIO::Job*);
+
+ private:
+ QString m_text;
+ QTextCodec* m_saveEncoding;
+ bool m_saveToPlainText;
+ KJotsEdit *m_editor; //!< ptr to editor if this is the active subject
+ int m_paraPos; //< used to remrmber the cursor position
+ int m_indexPos; //< used to remrmber the cursor position
+};
+
+#endif // __KJOTSENTRY_H
+/* ex: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab: */
diff --git a/kjots/kjotsui.rc b/kjots/kjotsui.rc
new file mode 100644
index 0000000..6c63a07
--- /dev/null
+++ b/kjots/kjotsui.rc
@@ -0,0 +1,41 @@
+<!DOCTYPE kpartgui>
+<kpartgui version="2" name="kjots" >
+ <MenuBar>
+
+ <Menu name="file">
+ <Action name="new_page" append="new_merge"/>
+ <Action name="new_book" append="new_merge"/>
+ <Separator/>
+ <Action name="save_page_to" append="save_merge"/>
+ <Action name="save_book_to" append="save_merge"/>
+ <Separator/>
+ <Action name="del_page" append="save_merge"/>
+ <Action name="del_folder" append="save_merge"/>
+ </Menu>
+
+ <Menu name="edit">
+ <Action name="copyIntoTitle" append="edit_paste_merge"/>
+ <Action name="rename_entry"/>
+ <Action name="insert_date"/>
+ </Menu>
+
+ <Menu name="go_document">
+ <Action name="go_next_page"/>
+ <Action name="go_prev_page"/>
+ <Separator/>
+ <Action name="go_next_book"/>
+ <Action name="go_prev_book"/>
+ </Menu>
+
+ <Action name="bookmarks"/>
+
+ <Menu name="settings"></Menu>
+
+ <Menu name="help"></Menu>
+ </MenuBar>
+
+ <ToolBar name="mainToolBar" fullWidth="true" >
+ <Separator/>
+ <Action name="insert_date"/>
+ </ToolBar>
+</kpartgui>
diff --git a/kjots/main.cpp b/kjots/main.cpp
new file mode 100644
index 0000000..4b0c10d
--- /dev/null
+++ b/kjots/main.cpp
@@ -0,0 +1,98 @@
+// -*- C++ -*-
+
+//
+// kjots
+//
+// Copyright (C) 1997 Christoph Neerfeld
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+#include <stdlib.h>
+#include <kuniqueapplication.h>
+#include <kcmdlineargs.h>
+#include <kconfig.h>
+#include <kaboutdata.h>
+
+#include "KJotsMain.h"
+
+
+static const char description[] = I18N_NOOP("KDE note taking utility");
+
+static const char version[] = "v0.7";
+
+
+int main( int argc, char **argv )
+{
+ KAboutData aboutData( "kjots", I18N_NOOP("KJots"),
+ version, description, KAboutData::License_GPL,
+ "(c) 1997-2002, Christoph Neerfeld");
+ aboutData.addAuthor("Pradeepto K. Bhattacharya", I18N_NOOP("Current maintainer"), "[email protected]");
+ aboutData.addAuthor("Jaison Lee", 0, "[email protected]");
+ aboutData.addAuthor("Aaron J. Seigo", 0, "[email protected]");
+ aboutData.addAuthor("Stanislav Kljuhhin", 0, "[email protected]");
+ aboutData.addAuthor("Christoph Neerfeld", I18N_NOOP("Original author"), "[email protected]");
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ KUniqueApplication::addCmdLineOptions();
+
+ if (!KUniqueApplication::start())
+ {
+ fprintf(stderr, "kjots is already running!\n");
+ exit(0);
+ }
+
+ KUniqueApplication a;
+
+ // backwards compatibility code to convert "old" user font settings
+ // to the new config settings
+ KConfig *config = a.config();
+ config->setGroup("kjots");
+ if (config->hasKey("EFontFamily")) {
+ // read old font and create it
+ QFont font( config->readEntry("EFontFamily"),
+ config->readNumEntry("EFontSize", 12),
+ config->readNumEntry("EFontWeight", 0),
+ config->readNumEntry("EFontItalic", 0));
+ // delete old entries
+ config->deleteEntry("EFontFamily");
+ config->deleteEntry("EFontSize");
+ config->deleteEntry("EFontWeight");
+ config->deleteEntry("EFontItalic");
+ config->deleteEntry("EFontCharset");
+ // write new "converted" entry
+ config->writeEntry("Font", font);
+ }
+
+ KJotsMain *jots = new KJotsMain;
+ if( a.isRestored() )
+ {
+ if( KJotsMain::canBeRestored(1) )
+ {
+ jots->restore(1);
+ }
+ }
+
+ a.setMainWidget( (QWidget *) jots );
+ jots->show();
+ jots->resize(jots->size());
+ return a.exec();
+}
+
+/* ex: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab: */