summaryrefslogtreecommitdiffstats
path: root/kjots/kjotsedit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kjots/kjotsedit.cpp')
-rw-r--r--kjots/kjotsedit.cpp483
1 files changed, 478 insertions, 5 deletions
diff --git a/kjots/kjotsedit.cpp b/kjots/kjotsedit.cpp
index 2b78698..b2ffe89 100644
--- a/kjots/kjotsedit.cpp
+++ b/kjots/kjotsedit.cpp
@@ -25,8 +25,13 @@
#include <tqcursor.h>
#include <tdepopupmenu.h>
-#include <keditcl.h>
+#include <kfind.h>
+#include <kfinddialog.h>
+#include <kreplace.h>
+#include <kreplacedialog.h>
+#include <kstringhandler.h>
#include <tdelocale.h>
+#include <tdemessagebox.h>
#include <kopenwith.h>
#include <kprinter.h>
@@ -37,8 +42,12 @@
// MYMULTIEDIT
//----------------------------------------------------------------------
KJotsEdit::KJotsEdit (TQWidget* parent, const char* name)
- : KEdit(parent, name),
- m_entry(0)
+ : KTextEdit(parent, name)
+ , m_entry(nullptr)
+ , m_find(nullptr)
+ , m_findDialog(nullptr)
+ , m_replace(nullptr)
+ , m_replaceDialog(nullptr)
{
// no rich text until printing and other such issues are worked out
setTextFormat(TQt::PlainText);
@@ -50,7 +59,8 @@ KJotsEdit::KJotsEdit (TQWidget* parent, const char* name)
KJotsEdit::~KJotsEdit()
{
-
+ delete m_find;
+ delete m_replace;
}
void KJotsEdit::mousePressEvent( TQMouseEvent *e )
@@ -67,7 +77,7 @@ void KJotsEdit::mousePressEvent( TQMouseEvent *e )
}
}
- KEdit::mousePressEvent(e);
+ KTextEdit::mousePressEvent(e);
}
void KJotsEdit::openUrl()
@@ -121,6 +131,441 @@ void KJotsEdit::print(TQString title)
}
}
+void KJotsEdit::slotFindHighlight(const TQString& text, int matchIndex, int matchLength)
+{
+ // tqDebug("KJotsEdit::slotFindHighlight");
+
+ Q_UNUSED(text);
+
+ const bool inSelection = m_find->options() & KFindDialog::SelectedText;
+
+ // Ensure we are offsetting the selection for the first line of the selection
+ // so we don't highlight the wrong text.
+ if (inSelection && (m_findCursor.paragraph == m_selectionStart.paragraph))
+ {
+ setSelection(m_findCursor.paragraph, m_selectionStart.paragraphIndex + matchIndex, m_findCursor.paragraph,
+ m_selectionStart.paragraphIndex + matchIndex + matchLength);
+ }
+ else
+ {
+ setSelection(m_findCursor.paragraph, matchIndex, m_findCursor.paragraph, matchIndex + matchLength);
+ }
+}
+
+void KJotsEdit::slotReplaceHighlight(const TQString& text, int matchIndex, int matchLength)
+{
+ // tqDebug("KJotsEdit::slotReplaceHighlight");
+
+ Q_UNUSED(text);
+
+ setSelection(m_replaceCursor.paragraph, matchIndex, m_replaceCursor.paragraph, matchIndex + matchLength);
+}
+
+void KJotsEdit::replace()
+{
+ // tqDebug("KJotsEdit::replace");
+
+ if (length() == 0)
+ {
+ return;
+ }
+
+ if (m_replaceDialog)
+ {
+ m_replaceDialog->setActiveWindow();
+ }
+ else
+ {
+ m_replaceDialog = new KReplaceDialog(this, "m_replaceDialog", KReplaceDialog::PromptOnReplace);
+ connect(m_replaceDialog, TQ_SIGNAL(okClicked()), this, TQ_SLOT(slotDoReplace()));
+ }
+
+ if (hasSelectedText())
+ {
+ m_replaceDialog->setHasSelection(true);
+ m_replaceDialog->setOptions(m_replaceDialog->options() | KReplaceDialog::SelectedText);
+ }
+ else
+ {
+ m_replaceDialog->setHasSelection(false);
+ m_replaceDialog->setOptions(m_replaceDialog->options() & ~KReplaceDialog::SelectedText);
+ }
+
+ m_replaceDialog->show();
+}
+
+void KJotsEdit::slotDoReplace()
+{
+ // tqDebug("KJotsEdit::slotDoReplace");
+
+ /* Performing a new replacement, so we need to remove the previous
+ * KReplace, set up a new one and the 'replaceNext' functionality. */
+
+ delete m_replace;
+ m_replace = nullptr;
+
+ if (!m_replaceDialog)
+ {
+ // tqDebug("KJotsEdit::slotDoReplace: no replaceDialog");
+ return;
+ }
+
+ m_replace = new KReplace(m_replaceDialog->pattern(), m_replaceDialog->replacement(), m_replaceDialog->options());
+
+ if ((m_replace->options() & KReplaceDialog::SelectedText))
+ {
+ const bool backwards = m_replace->options() & KFindDialog::FindBackwards;
+
+ getSelection(&m_selectionStart.paragraph, &m_selectionStart.paragraphIndex, &m_selectionEnd.paragraph,
+ &m_selectionEnd.paragraphIndex);
+ m_replaceCursor.paragraph = backwards ? m_selectionEnd.paragraph : m_selectionStart.paragraph;
+ m_replaceCursor.paragraphIndex = backwards ? m_selectionEnd.paragraphIndex : m_selectionStart.paragraphIndex;
+ }
+ else
+ {
+ setupCursor(&m_replaceCursor, m_replace);
+ }
+
+ connect(m_replace, TQ_SIGNAL(highlight(const TQString&, int, int)), this,
+ TQ_SLOT(slotReplaceHighlight(const TQString&, int, int)));
+ connect(m_replace, TQ_SIGNAL(findNext()), this, TQ_SLOT(slotReplaceNext()));
+ connect(m_replace, TQ_SIGNAL(replace(const TQString&, int, int, int)), this,
+ TQ_SLOT(slotReplace(const TQString&, int, int, int)));
+
+ m_replaceDialog->close();
+ slotReplaceNext();
+}
+
+void KJotsEdit::slotReplace(const TQString& replaceText, int replacementIndex, int replacementLength, int matchedLength)
+{
+ // tqDebug("KJotsEdit::slotReplace");
+
+ // Ensure the selection only matches the replacement.
+ // Prevents an issue where all the text is selected before replacing (since we remove the selection below).
+ setSelection(m_replaceCursor.paragraph, replacementIndex, m_replaceCursor.paragraph,
+ replacementIndex + matchedLength);
+
+ const auto replacement = replaceText.mid(replacementIndex, replacementLength);
+ removeSelectedText();
+ insertAt(replacement, m_replaceCursor.paragraph, replacementIndex);
+ setModified(true);
+}
+
+void KJotsEdit::slotReplaceNext()
+{
+ // tqDebug("KJotsEdit::slotReplaceNext");
+
+ if (!m_replace)
+ {
+ return;
+ }
+
+ const bool backwards = (m_replace->options() & KReplaceDialog::FindBackwards);
+ const bool useSelection = (m_replace->options() & KReplaceDialog::SelectedText);
+
+ if (m_replace->needData())
+ {
+ if (useSelection && backwards)
+ {
+ m_replace->setData(text(m_selectionEnd.paragraph), m_selectionEnd.paragraphIndex);
+ }
+ else if (useSelection)
+ {
+ m_replace->setData(text(m_selectionStart.paragraph), m_selectionStart.paragraphIndex);
+ }
+ else
+ {
+ m_replace->setData(text(m_replaceCursor.paragraph), m_replaceCursor.paragraphIndex);
+ }
+ }
+
+ KReplace::Result res = KReplace::NoMatch;
+
+ do
+ {
+ res = m_replace->replace();
+ if (res == KReplace::Match)
+ {
+ return;
+ }
+
+ m_replaceCursor.paragraph += (backwards ? -1 : 1);
+ m_replaceCursor.paragraphIndex = (backwards ? paragraphLength(m_replaceCursor.paragraph) : 0);
+ m_replace->setData(text(m_replaceCursor.paragraph), m_replaceCursor.paragraphIndex);
+
+ if (useSelection && m_replaceCursor.paragraph > m_selectionEnd.paragraph)
+ {
+ break;
+ }
+
+ if (useSelection && backwards && m_replaceCursor.paragraph < m_selectionStart.paragraph)
+ {
+ break;
+ }
+ } while (backwards ? (m_replaceCursor.paragraph >= 0) : (m_replaceCursor.paragraph < paragraphs()));
+
+ Q_ASSERT(res != KReplace::Match);
+
+ if ((m_replace->options() & KReplaceDialog::FromCursor) && m_replace->shouldRestart(true))
+ {
+ // tqDebug("KJotsEdit::slotReplaceNext restarting");
+ m_replaceCursor.paragraph = backwards ? (paragraphs() - 1) : 0;
+ m_replaceCursor.paragraphIndex = backwards ? (paragraphLength(m_replaceCursor.paragraph)) : 0;
+ m_replace->setData(text(m_replaceCursor.paragraph), m_replaceCursor.paragraphIndex);
+ m_replace->resetCounts();
+ slotReplaceNext();
+ return;
+ }
+
+ m_replace->displayFinalDialog();
+ m_replace->disconnect(this, TQ_SLOT(slotReplaceHighlight(const TQString&, int, int)));
+ m_replace->deleteLater();
+ m_replace = nullptr;
+}
+
+void KJotsEdit::find()
+{
+ // tqDebug("KJotsEdit::find");
+
+ if (length() == 0)
+ {
+ return;
+ }
+
+ if (m_findDialog)
+ {
+ m_findDialog->setActiveWindow();
+ }
+ else
+ {
+ m_findDialog = new KFindDialog(this, "m_findDialog");
+ connect(m_findDialog, TQ_SIGNAL(okClicked()), this, TQ_SLOT(slotDoFind()));
+ }
+
+ if (hasSelectedText())
+ {
+ m_findDialog->setHasSelection(true);
+ m_findDialog->setOptions(m_findDialog->options() | KFindDialog::SelectedText);
+ }
+ else
+ {
+ m_findDialog->setHasSelection(false);
+ m_findDialog->setOptions(m_findDialog->options() & ~KFindDialog::SelectedText);
+ }
+
+
+ m_findDialog->show();
+}
+
+void KJotsEdit::findNext()
+{
+ // tqDebug("KJotsEdit::findNext");
+
+ if (!m_find)
+ {
+ find();
+ return;
+ }
+
+ const bool backwards = (m_find->options() & KFindDialog::FindBackwards);
+ const bool fromCursor = (m_find->options() & KFindDialog::FromCursor);
+ const bool inSelection = (m_find->options() & KFindDialog::SelectedText);
+
+ if (m_find->needData())
+ {
+ if (inSelection)
+ {
+ if (m_selectionStart.paragraph == m_selectionEnd.paragraph)
+ {
+ // Same line, ensure we only inlcude the selection.
+ auto selectionLength = m_selectionEnd.paragraphIndex - m_selectionStart.paragraphIndex;
+ auto data = text(m_findCursor.paragraph).mid(m_selectionStart.paragraphIndex, selectionLength);
+ m_find->setData(data);
+ }
+ else if (backwards)
+ {
+ m_findCursor.paragraph = m_selectionEnd.paragraph;
+ m_findCursor.paragraphIndex = -1;
+ m_find->setData(text(m_findCursor.paragraph).left(m_selectionEnd.paragraphIndex));
+ }
+ else
+ {
+ m_findCursor.paragraph = m_selectionStart.paragraph;
+ m_findCursor.paragraphIndex = 0;
+ auto offset = (paragraphLength(m_findCursor.paragraph)) - m_selectionStart.paragraphIndex+1;
+ m_find->setData(text(m_findCursor.paragraph).right(offset), m_findCursor.paragraphIndex);
+ }
+ }
+ else
+ {
+ m_find->setData(text(m_findCursor.paragraph), m_findCursor.paragraphIndex);
+ }
+ }
+
+ KFind::Result res = KFind::NoMatch;
+
+ do
+ {
+ res = m_find->find();
+ if (res == KFind::Match)
+ {
+ return;
+ }
+
+ m_findCursor.paragraph += (backwards ? -1 : 1);
+ m_findCursor.paragraphIndex = -1; // SOL or EOL depending on `backwards`.
+
+ if (m_findCursor.paragraph == m_selectionStart.paragraph)
+ {
+ auto offset = (paragraphLength(m_findCursor.paragraph)) - m_selectionStart.paragraphIndex+1;
+ m_find->setData(text(m_findCursor.paragraph).right(offset), m_findCursor.paragraphIndex);
+ }
+ else if (m_findCursor.paragraph == m_selectionEnd.paragraph)
+ {
+ m_find->setData(text(m_findCursor.paragraph).left(m_selectionEnd.paragraphIndex), m_findCursor.paragraphIndex);
+ }
+ else
+ {
+ m_findCursor.paragraphIndex = -1;
+ m_find->setData(text(m_findCursor.paragraph), m_findCursor.paragraphIndex);
+ }
+
+ if (inSelection && backwards && m_findCursor.paragraph < m_selectionStart.paragraph)
+ {
+ break;
+ }
+
+ if (inSelection && m_findCursor.paragraph > m_selectionEnd.paragraph)
+ {
+ break;
+ }
+ } while (backwards ? (m_findCursor.paragraph >= 0) : (m_findCursor.paragraph < paragraphs()));
+
+ Q_ASSERT(res != KFind::Match);
+
+ // If there were no matches, and we were checking from the start of the text,
+ // then we do not want to prompt to search again, since we already know there
+ // is nothing.
+
+ if (m_find->numMatches() == 0 && !fromCursor)
+ {
+ KMessageBox::sorry(this,
+ i18n("Search string '%1' was not found!").arg(KStringHandler::csqueeze(m_find->pattern())));
+ // Reset the cursor in case more text is added between calls to findNext()
+ m_findCursor = m_selectionStart;
+ m_find->setData(text(m_selectionStart.paragraph)
+ .mid(m_selectionStart.paragraphIndex,
+ m_selectionEnd.paragraphIndex - m_selectionStart.paragraphIndex));
+ return;
+ }
+
+ if (m_find->shouldRestart(/* forceAsking */ true, /* showNumMatches */ false))
+ {
+ if (inSelection)
+ {
+ if (m_selectionStart.paragraph == m_selectionEnd.paragraph)
+ {
+ m_findCursor.paragraph = m_selectionStart.paragraph;
+ m_findCursor.paragraphIndex = m_selectionStart.paragraphIndex;
+ auto selectionLength = m_selectionEnd.paragraphIndex - m_selectionStart.paragraphIndex;
+ auto data = text(m_findCursor.paragraph).mid(m_findCursor.paragraphIndex, selectionLength);
+ m_find->setData(data);
+ }
+ else if (backwards)
+ {
+ m_findCursor = m_selectionEnd;
+ m_find->setData(text(m_findCursor.paragraph).left(m_findCursor.paragraphIndex));
+ }
+ else
+ {
+ m_findCursor.paragraph = m_selectionStart.paragraph;
+ m_findCursor.paragraphIndex = -1;
+ auto offset = (paragraphLength(m_findCursor.paragraph)) - m_selectionStart.paragraphIndex+1;
+ m_find->setData(text(m_findCursor.paragraph).right(offset), m_findCursor.paragraphIndex);
+ }
+ }
+ else
+ {
+ m_findCursor.paragraph = backwards ? (paragraphs() - 1) : 0;
+ m_findCursor.paragraphIndex = backwards ? (paragraphLength(m_findCursor.paragraph)) : 0;
+ m_find->setData(text(m_findCursor.paragraph), m_findCursor.paragraphIndex);
+ }
+
+ m_find->resetCounts();
+ findNext();
+ }
+}
+
+void KJotsEdit::findPrev()
+{
+ if (!m_find)
+ {
+ find();
+ return;
+ }
+
+ m_find->setOptions(m_find->options() ^ KFindDialog::FindBackwards);
+ findNext();
+
+ // Check as pressing 'stop' will delete m_find.
+ if (m_find)
+ {
+ m_find->setOptions(m_find->options() ^ KFindDialog::FindBackwards);
+ }
+}
+
+void KJotsEdit::slotDoFind()
+{
+ // tqDebug("KJotsEdit::slotDoFind");
+
+ /* Performing a new search, ensure the previous search is invalidated. */
+
+ delete m_find;
+ m_find = nullptr;
+
+ if (!m_findDialog)
+ {
+ // tqDebug("KJotsEdit::slotDoFind: find dialog not set up");
+ return;
+ }
+
+ if (m_findDialog->pattern().isEmpty())
+ {
+ // tqDebug("KJotsEdit::slotDoFind: empty pattern.");
+ return;
+ }
+
+ // tqDebug("findDialog->pattern = %s", m_findDialog->pattern().local8Bit().data());
+
+ m_find = new KFind(m_findDialog->pattern(), m_findDialog->options(), this);
+
+ if (m_find->options() & KFindDialog::SelectedText)
+ {
+ const bool backwards = m_find->options() & KFindDialog::FindBackwards;
+
+ getSelection(&m_selectionStart.paragraph, &m_selectionStart.paragraphIndex, &m_selectionEnd.paragraph,
+ &m_selectionEnd.paragraphIndex);
+ m_findCursor.paragraph = backwards ? m_selectionEnd.paragraph : m_selectionStart.paragraph;
+ m_findCursor.paragraphIndex = backwards ? m_selectionEnd.paragraphIndex : m_selectionStart.paragraphIndex;
+ }
+ else
+ {
+ setupCursor(&m_findCursor, m_find);
+ // Reset selection so slotFindHighlight works correctly.
+ m_selectionStart = {0, 0};
+ m_selectionEnd = {0, 0};
+ }
+
+ connect(m_find, TQ_SIGNAL(highlight(const TQString&, int, int)), this,
+ TQ_SLOT(slotFindHighlight(const TQString&, int, int)));
+ connect(m_find, TQ_SIGNAL(findNext()), this, TQ_SLOT(findNext()));
+
+ m_findDialog->close();
+ m_find->closeFindNextDialog();
+
+ findNext();
+}
+
void KJotsEdit::setEntry (KJotsPage *entry)
{
//tell the old entry to take a hike
@@ -144,6 +589,34 @@ void KJotsEdit::setEntry (KJotsPage *entry)
}
m_entry = entry;
+
+ // Reset the find & replace dialog for the new entry.
+ delete m_find;
+ delete m_replace;
+ m_find = nullptr;
+ m_replace = nullptr;
+}
+
+void KJotsEdit::setupCursor(KJotsEdit::CursorPosition* cursor, const KFind* find)
+{
+ if (!cursor)
+ {
+ tqWarning("WARNING: Attempting to setup a NULL cursor: %s (%d)", __FILE__, __LINE__);
+ return;
+ }
+
+ cursor->paragraph = 0;
+ cursor->paragraphIndex = 0;
+
+ if (find->options() & KFindDialog::FromCursor)
+ {
+ getCursorPosition(&cursor->paragraph, &cursor->paragraphIndex);
+ }
+ else if (find->options() & KFindDialog::FindBackwards)
+ {
+ cursor->paragraph = paragraphs();
+ cursor->paragraphIndex = paragraphLength(cursor->paragraph);
+ }
}
#include "kjotsedit.moc"