summaryrefslogtreecommitdiffstats
path: root/kjots/KJotsMain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kjots/KJotsMain.cpp')
-rw-r--r--kjots/KJotsMain.cpp1199
1 files changed, 1199 insertions, 0 deletions
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: */