diff options
Diffstat (limited to 'bibletime/frontend/display')
-rw-r--r-- | bibletime/frontend/display/Makefile.am | 24 | ||||
-rw-r--r-- | bibletime/frontend/display/cdisplay.cpp | 216 | ||||
-rw-r--r-- | bibletime/frontend/display/cdisplay.h | 189 | ||||
-rw-r--r-- | bibletime/frontend/display/chtmlreaddisplay.cpp | 507 | ||||
-rw-r--r-- | bibletime/frontend/display/chtmlreaddisplay.h | 144 | ||||
-rw-r--r-- | bibletime/frontend/display/chtmlwritedisplay.cpp | 266 | ||||
-rw-r--r-- | bibletime/frontend/display/chtmlwritedisplay.h | 104 | ||||
-rw-r--r-- | bibletime/frontend/display/cplainwritedisplay.cpp | 157 | ||||
-rw-r--r-- | bibletime/frontend/display/cplainwritedisplay.h | 94 | ||||
-rw-r--r-- | bibletime/frontend/display/creaddisplay.cpp | 115 | ||||
-rw-r--r-- | bibletime/frontend/display/creaddisplay.h | 71 | ||||
-rw-r--r-- | bibletime/frontend/display/cwritedisplay.cpp | 23 | ||||
-rw-r--r-- | bibletime/frontend/display/cwritedisplay.h | 50 |
13 files changed, 1960 insertions, 0 deletions
diff --git a/bibletime/frontend/display/Makefile.am b/bibletime/frontend/display/Makefile.am new file mode 100644 index 0000000..7a79921 --- /dev/null +++ b/bibletime/frontend/display/Makefile.am @@ -0,0 +1,24 @@ +INCLUDES = $(all_includes) + +libdisplay_a_METASOURCES = AUTO + +noinst_LIBRARIES = libdisplay.a + +libdisplay_a_SOURCES = \ +cdisplay.cpp \ +creaddisplay.cpp \ +chtmlreaddisplay.cpp \ +cwritedisplay.cpp \ +cplainwritedisplay.cpp \ +chtmlwritedisplay.cpp + +all_headers = \ +cdisplay.h \ +creaddisplay.h \ +chtmlreaddisplay.h \ +cwritedisplay.h \ +cplainwritedisplay.h \ +chtmlwritedisplay.h + +EXTRA_DIST = $(libdisplay_a_SOURCES) $(all_headers) + diff --git a/bibletime/frontend/display/cdisplay.cpp b/bibletime/frontend/display/cdisplay.cpp new file mode 100644 index 0000000..ce97e02 --- /dev/null +++ b/bibletime/frontend/display/cdisplay.cpp @@ -0,0 +1,216 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2006 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + + +#include "cdisplay.h" +#include "chtmlreaddisplay.h" +#include "cplainwritedisplay.h" +#include "chtmlwritedisplay.h" + +#include "backend/creferencemanager.h" + +#include "util/ctoolclass.h" + + +//Qt includes +#include <qclipboard.h> +#include <qpopupmenu.h> +#include <qtimer.h> + +//KDE includes +#include <kapplication.h> +#include <kfiledialog.h> +#include <klocale.h> + + +CDisplayConnections::CDisplayConnections( CDisplay* display ) : m_display(display) {} + +void CDisplayConnections::selectAll() { + m_display->selectAll(); +} + +void CDisplayConnections::saveAsHTML() { + m_display->save(CDisplay::HTMLText, CDisplay::Document); +} + +void CDisplayConnections::saveAsPlain() { + m_display->save(CDisplay::PlainText, CDisplay::Document); +} + +/** Emits the signal. */ +void CDisplayConnections::emitReferenceClicked( const QString& module, const QString& key) { + emit referenceClicked( module, key ); +} + +/** Emits the signal. */ +void CDisplayConnections::emitReferenceDropped( const QString& key) { + emit referenceDropped(key); +} + +/** Emits the signal. */ +void CDisplayConnections::emitTextChanged() { + emit textChanged(); +} + +void CDisplayConnections::copyAll() { + m_display->copy(CDisplay::PlainText, CDisplay::Document); +} + +/** No descriptions */ +void CDisplayConnections::copySelection() { + qWarning("copyign the selected text"); + m_display->copy(CDisplay::PlainText, CDisplay::SelectedText); +} + +void CDisplayConnections::printAll(CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) { + m_display->print(CDisplay::Document, displayOptions, filterOptions); +} + +void CDisplayConnections::printAnchorWithText(CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) { + m_display->print(CDisplay::AnchorWithText, displayOptions, filterOptions); +} + +void CDisplayConnections::copyAnchorOnly() { + m_display->copy(CDisplay::PlainText, CDisplay::AnchorOnly); +} + +void CDisplayConnections::copyAnchorTextOnly() { + m_display->copy(CDisplay::PlainText, CDisplay::AnchorTextOnly); +} + +void CDisplayConnections::copyAnchorWithText() { + m_display->copy(CDisplay::PlainText, CDisplay::AnchorWithText); +} + +void CDisplayConnections::saveAnchorWithText() { + m_display->save(CDisplay::PlainText, CDisplay::AnchorWithText); +} + +void CDisplayConnections::clear() { + m_display->setText(QString::null); +} + +void CDisplayConnections::zoomIn() { + m_display->zoomIn(); +} + +void CDisplayConnections::zoomOut() { + m_display->zoomOut(); +} + +void CDisplayConnections::openFindTextDialog() { + m_display->openFindTextDialog(); +} + + +/*----------------------*/ + +CReadDisplay* CDisplay::createReadInstance( CReadWindow* readWindow, QWidget* parent ) { + return new CHTMLReadDisplay(readWindow, parent); +} + +CWriteDisplay* CDisplay::createWriteInstance( CWriteWindow* writeWindow, const CWriteDisplay::WriteDisplayType& type, QWidget* parent ) { + // qWarning("CDisplay::createWriteInstance"); + if (type == PlainTextDisplay) { + return new CPlainWriteDisplay(writeWindow, parent); + } + else { + return new CHTMLWriteDisplay(writeWindow, parent); + }; +} + + +CDisplay::CDisplay(CDisplayWindow* parent) : +m_parentWindow(parent), +m_connections( new CDisplayConnections( this ) ), +m_popup(0) {} + +CDisplay::~CDisplay() { + delete m_connections; +} + +const bool CDisplay::copy( const CDisplay::TextType format, const CDisplay::TextPart part ) { + const QString content = text(format, part); + + QClipboard* cb = KApplication::clipboard(); + cb->setText(content); + return true; +} + +const bool CDisplay::save( const CDisplay::TextType format, const CDisplay::TextPart part ) { + // qWarning("CDisplay::save( const CDisplay::TextType format, const CDisplay::TextPart part )"); + const QString content = text(format, part); + QString filter = QString::null; + + switch (format) { + case HTMLText: + filter = QString("*.html *.htm | ") + i18n("HTML files") + QString("\n *.* | All files (*.*)"); + break; + case PlainText: + filter = QString("*.txt | ") + i18n("Text files") + QString("\n *.* | All files (*.*)"); + break; + }; + + const QString filename = KFileDialog::getSaveFileName(QString::null, filter, 0, i18n("Save document ...")); + + if (!filename.isEmpty()) { + CToolClass::savePlainFile(filename, content); + } + return true; +} + +/** Emits the signal which used when a reference was clicked. */ +void CDisplay::emitReferenceClicked( const QString& reference ) { + qWarning("reference clicked %s", reference.latin1()); + QString module; + QString key; + CReferenceManager::Type type; + /*const bool ok = */ + CReferenceManager::decodeHyperlink(reference, module, key, type); + if (module.isEmpty()) { + module = CReferenceManager::preferredModule( type ); + } + m_connections->emitReferenceClicked(module, key); +} + +/** Used when a reference was dropped onto the widget. */ +void CDisplay::emitReferenceDropped( const QString& reference ) { + QString module; + QString key; + CReferenceManager::Type type; + /*const bool ok = */ + CReferenceManager::decodeHyperlink(reference, module, key, type); + // if (module.isEmpty()) { + // module = CReferenceManager::preferredModule( type ); + // } + + m_connections->emitReferenceDropped(key); +} + +/** Returns the connections obect used for signas and slots. */ +CDisplayConnections* const CDisplay::connectionsProxy() const { + return m_connections; +} + +CDisplayWindow* const CDisplay::parentWindow() const { + return m_parentWindow; +} + +/** Installs the popup which should be opened when the right mouse button was pressed. */ +void CDisplay::installPopup( QPopupMenu* popup ) { + m_popup = popup; +} + +/** Returns the popup menu which was set by installPopupMenu() */ +QPopupMenu* const CDisplay::installedPopup() { + Q_ASSERT(m_popup); + return m_popup; +} + diff --git a/bibletime/frontend/display/cdisplay.h b/bibletime/frontend/display/cdisplay.h new file mode 100644 index 0000000..d37692c --- /dev/null +++ b/bibletime/frontend/display/cdisplay.h @@ -0,0 +1,189 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2006 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + + +#ifndef CDISPLAY_H +#define CDISPLAY_H + +//BibleTime includes +#include "util/cpointers.h" +#include "backend/cswordbackend.h" + +//Qt includes +#include <qobject.h> +#include <qstring.h> +#include <qmap.h> + + +class CDisplayConnections; +class CReadWindow; +class CWriteWindow; + +class CDisplayWindow; +class CReadDisplay; +class CWriteDisplay; + + +class QPopupMenu; + +/** The base class for all display widgets. + * @author The BibleTime team + */ +class CDisplay : public CPointers { +public: + enum WriteDisplayType { + HTMLDisplay = 0, + PlainTextDisplay + }; + + static CReadDisplay* createReadInstance(CReadWindow* readWindow, QWidget* parent = 0); + static CWriteDisplay* createWriteInstance( CWriteWindow* writeWindow, const WriteDisplayType& type = PlainTextDisplay, QWidget* parent = 0 ); + + enum TextType { + HTMLText, /* Used for HTML markup */ + PlainText /* Plain text without links etc. */ + }; + enum TextPart { + Document, /* All text */ + SelectedText, /* Only the selected text */ + AnchorOnly, + AnchorTextOnly, + AnchorWithText + }; + + /** + * Copies the given text with the specified format into the applications clipboard. + */ + virtual const bool copy( const CDisplay::TextType format, const CDisplay::TextPart part ); + /** + * Saves the given text with the specified format into the applications clipboard. + */ + virtual const bool save( const CDisplay::TextType format, const CDisplay::TextPart part ); + + //the pure virtual methods of this base class + + /** Returns the text in the given format. + * + */ + virtual const QString text( const CDisplay::TextType format = CDisplay::HTMLText, const CDisplay::TextPart part = CDisplay::Document ) = 0; + /** + * Sets the new text for this display widget. + */ + virtual void setText( const QString& newText ) = 0; + /** + * Returns true if the display widget has a selection. Otherwise false. + */ + virtual const bool hasSelection() = 0; + /** + * Returns the view of this display widget. + */ + virtual QWidget* view() = 0; + /** + * Selects the document text. + */ + virtual void selectAll() = 0; + /** + * Returns the connections obect used for signas and slots. + */ + virtual CDisplayConnections* const connectionsProxy() const; + /** + * Returns the parent window used for this display widget. + */ + CDisplayWindow* const parentWindow() const; + virtual void print( const CDisplay::TextPart, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) = 0; + /** + * Installs the popup which should be opened when the right mouse button was pressed. + */ + void installPopup( QPopupMenu* popup ); + /** + * Returns the popup menu which was set by installPopupMenu() + */ + QPopupMenu* const installedPopup(); + + virtual void zoomIn() {} + virtual void zoomOut() {} + virtual void openFindTextDialog() {} + + enum NodeInfoType { + Lemma + }; + + + virtual QMap<NodeInfoType, QString> getCurrentNodeInfo() { + return QMap<NodeInfoType, QString>(); + } + +protected: + /** + * Used when a reference was dropped onto the widget. + */ + void emitReferenceDropped( const QString& reference ); + /** + * Emits the signal which used when a reference was clicked. + */ + void emitReferenceClicked( const QString& reference ); + +protected: + CDisplay(CDisplayWindow* parent); + virtual ~CDisplay(); + +private: + CDisplayWindow* m_parentWindow; + CDisplayConnections* m_connections; + QPopupMenu* m_popup; +}; + +class CDisplayConnections : public QObject { + Q_OBJECT +public: + CDisplayConnections( CDisplay* parent ); + +public slots: + virtual void selectAll(); + void emitReferenceClicked( const QString& module, const QString& key); + void emitReferenceDropped( const QString& key ); + void emitTextChanged(); + + //stuff which works in every CDisplay + void saveAsPlain(); + void saveAsHTML(); + void saveAnchorWithText(); + + void printAll(CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions); + void printAnchorWithText(CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions); + + void copySelection(); + void copyAll(); + void copyAnchorWithText(); + void copyAnchorTextOnly(); + void copyAnchorOnly(); + + void clear(); + + void zoomIn(); + void zoomOut(); + + void openFindTextDialog(); + +signals: + void referenceClicked(const QString& module, const QString& key); + void referenceDropped(const QString& key); + void textChanged(); + +private: + CDisplay* m_display; + + struct { + QString module; + QString key; + } m_referenceClickedCache; +}; + +#endif diff --git a/bibletime/frontend/display/chtmlreaddisplay.cpp b/bibletime/frontend/display/chtmlreaddisplay.cpp new file mode 100644 index 0000000..4219f33 --- /dev/null +++ b/bibletime/frontend/display/chtmlreaddisplay.cpp @@ -0,0 +1,507 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2006 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + + +#include "chtmlreaddisplay.h" + +#include "frontend/displaywindow/cdisplaywindow.h" +#include "frontend/displaywindow/creadwindow.h" +#include "backend/creferencemanager.h" +#include "backend/cswordkey.h" + +#include "frontend/cbtconfig.h" +#include "frontend/cdragdropmgr.h" +#include "frontend/cinfodisplay.h" + +#include "util/ctoolclass.h" +#include "util/cpointers.h" +#include "util/scoped_resource.h" + +//We will need to reference this in the Qt includes +#include <kdeversion.h> + +//Qt includes +#include <qcursor.h> +#include <qscrollview.h> +#include <qwidget.h> +#include <qdragobject.h> +#include <qpopupmenu.h> +#include <qlayout.h> +#include <qtimer.h> +#if KDE_VERSION < 0x030300 +//We will need to show the error message. +#include <qmessagebox.h> +#endif + +//KDE includes +#include <kapplication.h> +#include <khtmlview.h> +#include <kglobalsettings.h> +#include <khtml_events.h> + +#include <dom/dom2_range.h> +#include <dom/html_element.h> +#include <dom/dom2_traversal.h> + +using namespace InfoDisplay; + +CHTMLReadDisplay::CHTMLReadDisplay(CReadWindow* readWindow, QWidget* parentWidget) +: KHTMLPart((m_view = new CHTMLReadDisplayView(this, parentWidget ? parentWidget : readWindow)), readWindow ? readWindow : parentWidget), +CReadDisplay(readWindow), +m_currentAnchorCache(QString::null) { + setDNDEnabled(false); + setJavaEnabled(false); + setJScriptEnabled(false); + setPluginsEnabled(false); + + m_view->setDragAutoScroll(false); + +} + +CHTMLReadDisplay::~CHTMLReadDisplay() {} + +const QString CHTMLReadDisplay::text( const CDisplay::TextType format, const CDisplay::TextPart part) { + + switch (part) { + case Document: { + if (format == HTMLText) { + return document().toHTML(); + } + else { + CDisplayWindow* window = parentWindow(); + CSwordKey* const key = window->key(); + CSwordModuleInfo* module = key->module(); + //return htmlDocument().body().innerText().string().latin1(); + //This function is never used for Bibles, so it is not + //implemented. If it should be, see CReadDisplay::print() for + //example code. + Q_ASSERT(module->type() == CSwordModuleInfo::Lexicon || module->type() == CSwordModuleInfo::Commentary || module->type() == CSwordModuleInfo::GenericBook); + if (module->type() == CSwordModuleInfo::Lexicon || module->type() == CSwordModuleInfo::Commentary || module->type() == CSwordModuleInfo::GenericBook) { + //TODO: This is a BAD HACK, we have to fnd a better solution to manage the settings now + CSwordBackend::FilterOptions filterOptions; + filterOptions.footnotes = false; + filterOptions.strongNumbers = false; + filterOptions.morphTags = false; + filterOptions.lemmas = false; + filterOptions.scriptureReferences = false; + filterOptions.textualVariants = false; + + CPointers::backend()->setFilterOptions(filterOptions); + + return QString(key->strippedText()).append("\n(") + .append(key->key()) + .append(", ") + .append(key->module()->name()) + .append(")"); + } + } + } + + case SelectedText: { + if (!hasSelection()) { + return QString::null; + } + else if (format == HTMLText) { + DOM::Range range = selection(); + return range.toHTML().string(); + } + else { //plain text requested + return selectedText(); + } + } + + case AnchorOnly: { + QString moduleName; + QString keyName; + CReferenceManager::Type type; + CReferenceManager::decodeHyperlink(activeAnchor(), moduleName, keyName, type); + + return keyName; + } + + case AnchorTextOnly: { + QString moduleName; + QString keyName; + CReferenceManager::Type type; + CReferenceManager::decodeHyperlink(activeAnchor(), moduleName, keyName, type); + + if (CSwordModuleInfo* module = backend()->findModuleByName(moduleName)) { + util::scoped_ptr<CSwordKey> key( CSwordKey::createInstance(module) ); + key->key( keyName ); + + return key->strippedText(); + } + return QString::null; + } + + case AnchorWithText: { + QString moduleName; + QString keyName; + CReferenceManager::Type type; + CReferenceManager::decodeHyperlink(activeAnchor(), moduleName, keyName, type); + + if (CSwordModuleInfo* module = backend()->findModuleByName(moduleName)) { + util::scoped_ptr<CSwordKey> key( CSwordKey::createInstance(module) ); + key->key( keyName ); + + //TODO: This is a BAD HACK, we have to fnd a better solution to manage the settings now + CSwordBackend::FilterOptions filterOptions; + filterOptions.footnotes = false; + filterOptions.strongNumbers = false; + filterOptions.morphTags = false; + filterOptions.lemmas = false; + filterOptions.scriptureReferences = false; + filterOptions.textualVariants = false; + + CPointers::backend()->setFilterOptions(filterOptions); + + return QString(key->strippedText()).append("\n(") + .append(key->key()) + .append(", ") + .append(key->module()->name()) + .append(")"); + /* ("%1\n(%2, %3)") + .arg() + .arg(key->key()) + .arg(key->module()->name());*/ + } + return QString::null; + } + default: + return QString::null; + } +} + +void CHTMLReadDisplay::setText( const QString& newText ) { + begin(); + write(newText); + end(); +} + +/** No descriptions */ +const bool CHTMLReadDisplay::hasSelection() { + return KHTMLPart::hasSelection(); +} + + +/** Reimplementation. */ +QScrollView* CHTMLReadDisplay::view() { + return KHTMLPart::view(); +} + +void CHTMLReadDisplay::selectAll() { + KHTMLPart::selectAll(); +} + +/** No descriptions */ +void CHTMLReadDisplay::moveToAnchor( const QString& anchor ) { + m_currentAnchorCache = anchor; + + //This is an ugly hack to work around a KDE problem in KDE including 3.3.1 (no later versions tested so far) + QTimer::singleShot(0, this, SLOT(slotGoToAnchor())); + + // instead of: + // slotGoToAnchor(); +} + +void CHTMLReadDisplay::urlSelected( const QString& url, int button, int state, const QString& _target, KParts::URLArgs args) { + KHTMLPart::urlSelected(url, button, state, _target, args); + m_urlWorkaroundData.doWorkaround = false; + // qWarning("clicked: %s", url.latin1()); + if (!url.isEmpty() && CReferenceManager::isHyperlink(url)) { + QString module; + QString key; + CReferenceManager::Type type; + + CReferenceManager::decodeHyperlink(url, module, key, type); + if (module.isEmpty()) { + module = CReferenceManager::preferredModule( type ); + } + + // we have to use this workaround, otherwise the widget would scroll because it was interrupted + // between mouseClick and mouseRelease (I guess) + m_urlWorkaroundData.doWorkaround = true; + m_urlWorkaroundData.url = url; + m_urlWorkaroundData.state = state; + m_urlWorkaroundData.button = button; + m_urlWorkaroundData.target = _target; + m_urlWorkaroundData.args = args; + m_urlWorkaroundData.module = module; + m_urlWorkaroundData.key = key; + } + else if (!url.isEmpty() && (url.left(1) == "#")) { //anchor + moveToAnchor(url.mid(1)); + } + else if (url.left(7) == "http://") { //open the bowser configured by kdeb + KApplication::kApplication()->invokeBrowser( url ); //ToDo: Not yet tested + } +} + +/** Reimplementation. */ +void CHTMLReadDisplay::khtmlMouseReleaseEvent( khtml::MouseReleaseEvent* event ) { + KHTMLPart::khtmlMouseReleaseEvent(event); + + m_dndData.mousePressed = false; + m_dndData.isDragging = false; + m_dndData.node = DOM::Node(); + m_dndData.anchor = DOM::DOMString(); + + if (m_urlWorkaroundData.doWorkaround) { + m_urlWorkaroundData.doWorkaround = false; + connectionsProxy()->emitReferenceClicked( + m_urlWorkaroundData.module, + m_urlWorkaroundData.key + ); + } +} + +void CHTMLReadDisplay::khtmlMousePressEvent( khtml::MousePressEvent* event ) { + m_dndData.node = DOM::Node(); + m_dndData.anchor = DOM::DOMString(); + m_dndData.mousePressed = false; + m_dndData.isDragging = false; + + if (event->qmouseEvent()->button() == Qt::RightButton) { + DOM::Node tmpNode = event->innerNode(); + DOM::Node attr; + m_nodeInfo[CDisplay::Lemma] = QString::null; + + do { + if (!tmpNode.isNull() && (tmpNode.nodeType() == + DOM::Node::ELEMENT_NODE) && tmpNode.hasAttributes()) { + attr = tmpNode.attributes().getNamedItem("lemma"); + if (!attr.isNull()) { + m_nodeInfo[ CDisplay::Lemma ] = attr.nodeValue().string(); + break; + } + } + tmpNode = tmpNode.parentNode(); + } while ( !tmpNode.isNull() ); + + setActiveAnchor( event->url().string() ); + } + else if (event->qmouseEvent()->button() == Qt::LeftButton) { + m_dndData.node = event->innerNode(); + m_dndData.anchor = event->url(); + m_dndData.mousePressed = true; + m_dndData.isDragging = false; + m_dndData.startPos = QPoint(event->x(), event->y()); + m_dndData.selection = selectedText(); + + if (!m_dndData.node.isNull()) { //we drag a valid link + m_dndData.dragType = DNDData::Link; + } + } + + KHTMLPart::khtmlMousePressEvent(event); +} + +/** Reimplementation for our drag&drop system. Also needed for the mouse tracking */ +void CHTMLReadDisplay::khtmlMouseMoveEvent( khtml::MouseMoveEvent* e ) { + if( e->qmouseEvent()->state() & LeftButton == LeftButton) { //left mouse button pressed + const int delay = KGlobalSettings::dndEventDelay(); + QPoint newPos = QPoint(e->x(), e->y()); + + if ( (newPos.x() > m_dndData.startPos.x()+delay || newPos.x() < (m_dndData.startPos.x()-delay) || + newPos.y() > m_dndData.startPos.y()+delay || newPos.y() < (m_dndData.startPos.y()-delay)) && + !m_dndData.isDragging && m_dndData.mousePressed ) { + QDragObject* d = 0; + if (!m_dndData.anchor.isEmpty() && (m_dndData.dragType == DNDData::Link) && !m_dndData.node.isNull() ) { + // create a new bookmark drag! + QString module = QString::null; + QString key = QString::null; + CReferenceManager::Type type; + if ( !CReferenceManager::decodeHyperlink(m_dndData.anchor.string(), module, key, type) ) + return; + + CDragDropMgr::ItemList dndItems; + //no description! + dndItems.append( CDragDropMgr::Item(module, key, QString::null) ); + d = CDragDropMgr::dragObject(dndItems, KHTMLPart::view()->viewport()); + } + else if ((m_dndData.dragType == DNDData::Text) && !m_dndData.selection.isEmpty()) { + // create a new plain text drag! + CDragDropMgr::ItemList dndItems; + dndItems.append( CDragDropMgr::Item(m_dndData.selection) ); //no description! + d = CDragDropMgr::dragObject(dndItems, KHTMLPart::view()->viewport()); + } + + if (d) { + m_dndData.isDragging = true; + m_dndData.mousePressed = false; + + //first make a virtual mouse click to end the selection, it it's in progress + QMouseEvent e(QEvent::MouseButtonRelease, QPoint(0,0), Qt::LeftButton, Qt::LeftButton); + KApplication::sendEvent(view()->viewport(), &e); + d->drag(); + } + } + } + else if (getMouseTracking() && !(e->qmouseEvent()->state() & Qt::ShiftButton == Qt::ShiftButton)) { + //no mouse button pressed and tracking enabled + DOM::Node node = e->innerNode(); + //if no link was under the mouse try to find a title attribute + if (!node.isNull() && (m_previousEventNode != node)) { + // we want to avoid processing the node again + // After some millisecs the new timer activates the Mag window update, see timerEvent() + // SHIFT key not pressed, so we start timer + if ( !(e->qmouseEvent()->state() & Qt::ShiftButton)) { + // QObject has simple timer + killTimers(); + startTimer( CBTConfig::get(CBTConfig::magDelay) ); + } + + m_previousEventNode = node; + } + } + + KHTMLPart::khtmlMouseMoveEvent(e); +} + +/** The Mag window update happens here if the mouse has not moved to another node after starting the timer.*/ +void CHTMLReadDisplay::timerEvent( QTimerEvent *e ) { + killTimers(); + DOM::Node currentNode = nodeUnderMouse(); + CInfoDisplay::ListInfoData infoList; + + // Process the node under cursor if it is the same as at the start of the timer + if (!currentNode.isNull() && (currentNode != m_previousEventNode) && this->view()->hasMouse()) { + DOM::Node attr; + do { + if (!currentNode.isNull() && (currentNode.nodeType() == DOM::Node::ELEMENT_NODE) && currentNode.hasAttributes()) { //found right node + attr = currentNode.attributes().getNamedItem("note"); + if (!attr.isNull()) { + infoList.append( qMakePair(CInfoDisplay::Footnote, attr.nodeValue().string()) ); + } + + attr = currentNode.attributes().getNamedItem("lemma"); + if (!attr.isNull()) { + infoList.append( qMakePair(CInfoDisplay::Lemma, attr.nodeValue().string()) ); + } + + attr = currentNode.attributes().getNamedItem("morph"); + if (!attr.isNull()) { + infoList.append( qMakePair(CInfoDisplay::Morph, attr.nodeValue().string()) ); + } + + attr = currentNode.attributes().getNamedItem("expansion"); + if (!attr.isNull()) { + infoList.append( qMakePair(CInfoDisplay::Abbreviation, attr.nodeValue().string()) ); + } + + attr = currentNode.attributes().getNamedItem("crossrefs"); + if (!attr.isNull()) { + infoList.append( qMakePair(CInfoDisplay::CrossReference, attr.nodeValue().string()) ); + } + } + + currentNode = currentNode.parentNode(); + if (!currentNode.isNull() && currentNode.hasAttributes()) { + attr = currentNode.attributes().getNamedItem("class"); + if (!attr.isNull() && (attr.nodeValue().string() == "entry") || (attr.nodeValue().string() == "currententry") ) { + break; + } + } + } + while ( !currentNode.isNull() ); + } + + // Update the mag if there is new content + if (!(infoList.isEmpty())) { + CPointers::infoDisplay()->setInfo(infoList); + } + +} + +// --------------------- + +CHTMLReadDisplayView::CHTMLReadDisplayView(CHTMLReadDisplay* displayWidget, QWidget* parent) : KHTMLView(displayWidget, parent), m_display(displayWidget) { + viewport()->setAcceptDrops(true); + setMarginWidth(4); + setMarginHeight(4); +}; + + +/** Opens the popupmenu at the given position. */ +void CHTMLReadDisplayView::popupMenu( const QString& url, const QPoint& pos) { + if (!url.isEmpty()) { + m_display->setActiveAnchor(url); + } + if (QPopupMenu* popup = m_display->installedPopup()) { + popup->exec(pos); + } +} + +/** Reimplementation from QScrollView. Sets the right slots */ +void CHTMLReadDisplayView::polish() { + KHTMLView::polish(); + connect( part(), SIGNAL(popupMenu(const QString&, const QPoint&)), + this, SLOT(popupMenu(const QString&, const QPoint&))); +} + +/** Reimplementatiob from QScrollView. */ +void CHTMLReadDisplayView::contentsDropEvent( QDropEvent* e ) { + if (CDragDropMgr::canDecode(e) && CDragDropMgr::dndType(e) == CDragDropMgr::Item::Bookmark) { + CDragDropMgr::ItemList dndItems = CDragDropMgr::decode(e); + CDragDropMgr::Item item = dndItems.first(); + e->acceptAction(); + + m_display->connectionsProxy()->emitReferenceDropped(item.bookmarkKey()); + return; + }; + + //don't accept the action! + e->acceptAction(false); + e->ignore(); +} + +/** Reimplementation from QScrollView. */ +void CHTMLReadDisplayView::contentsDragEnterEvent( QDragEnterEvent* e ) { + if (CDragDropMgr::canDecode(e) && CDragDropMgr::dndType(e) == CDragDropMgr::Item::Bookmark) { + e->acceptAction(); + return; + } + + e->acceptAction(false); + e->ignore(); +} + +/*! +\fn CHTMLReadDisplay::slotPageLoaded() +*/ +void CHTMLReadDisplay::slotGoToAnchor() { + if (!m_currentAnchorCache.isEmpty()) { + if (!gotoAnchor( m_currentAnchorCache ) ) { + qDebug("anchor %s not present!", m_currentAnchorCache.latin1()); + } + } + m_currentAnchorCache = QString::null; +} + +void CHTMLReadDisplay::zoomIn() { + setZoomFactor( (int)((float)zoomFactor()*1.1) ); +} + +void CHTMLReadDisplay::zoomOut() { + setZoomFactor( (int)((float)zoomFactor()*(1.0/1.1)) ); +} + +void CHTMLReadDisplay::openFindTextDialog() { +#if KDE_VERSION >= 0x030300 + findText(); +#else + QMessageBox::information(0, "Not Supported", + "This copy of BibleTime was built against a version of KDE older\n" + "than 3.3 (probably due to your distro), so this search feature\n" + "does not work.\n\n" + "This is a known issue. If we do not have a fix for the next\n" + "version of BibleTime, we will remove the option."); +#endif +} diff --git a/bibletime/frontend/display/chtmlreaddisplay.h b/bibletime/frontend/display/chtmlreaddisplay.h new file mode 100644 index 0000000..5b875cf --- /dev/null +++ b/bibletime/frontend/display/chtmlreaddisplay.h @@ -0,0 +1,144 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2006 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + + +#ifndef CHTMLREADDISPLAY_H +#define CHTMLREADDISPLAY_H + +//BibleTime includes +#include "creaddisplay.h" +//#include "frontend/ctooltip.h" + +//Qt includes +#include <qstring.h> +#include <qwidget.h> + +//KDE includes +#include <khtml_part.h> +#include <khtmlview.h> +#include <kparts/browserextension.h> + +class CHTMLReadDisplayView; + +/** The implementation for the HTML read display. + * @author The BibleTime team + */ +class CHTMLReadDisplay : public KHTMLPart, public CReadDisplay { + Q_OBJECT +public: + //reimplemented functions from CDisplay + /** + * Returns the right text part in the specified format. + */ + virtual const QString text( const CDisplay::TextType format = CDisplay::HTMLText, const CDisplay::TextPart part = CDisplay::Document ); + /** + * Sets the new text for this display widget. + */ + virtual void setText( const QString& newText ); + virtual const bool hasSelection(); + /** + * Reimplementation. + */ + virtual QScrollView* view(); + virtual void selectAll(); + virtual void moveToAnchor( const QString& anchor ); + + virtual void zoomIn(); + virtual void zoomOut(); + virtual void openFindTextDialog(); + + virtual QMap<CDisplay::NodeInfoType, QString> getCurrentNodeInfo() { + return m_nodeInfo; + } + +protected: + friend class CDisplay; + CHTMLReadDisplay( CReadWindow* readWindow, QWidget* parent = 0 ); + virtual ~CHTMLReadDisplay(); + + virtual void urlSelected( const QString& url, int button, int state, const QString& _target, KParts::URLArgs args); + /** + * Reimplementation. + */ + virtual void khtmlMouseReleaseEvent( khtml::MouseReleaseEvent* event ); + virtual void khtmlMousePressEvent( khtml::MousePressEvent* event ); + virtual void khtmlMouseMoveEvent( khtml::MouseMoveEvent* event ); + virtual void timerEvent(QTimerEvent *event); + + + struct DNDData { + bool mousePressed; + bool isDragging; + DOM::Node node; + DOM::DOMString anchor; + QString selection; + QPoint startPos; + enum DragType { + Link, + Text + } dragType; + } + m_dndData; + + QMap<NodeInfoType, QString> m_nodeInfo; + +private: + CHTMLReadDisplayView* m_view; + struct URLWorkaroundData { + bool doWorkaround; + QString url; + int button; + int state; + QString target; + KParts::URLArgs args; + + QString module; + QString key; + } + m_urlWorkaroundData; + + DOM::Node m_previousEventNode; + QString m_currentAnchorCache; + +protected slots: + void slotGoToAnchor(); +}; + +class CHTMLReadDisplayView : public KHTMLView, public CPointers { + Q_OBJECT +protected: // Protected methods + friend class CHTMLReadDisplay; + + + CHTMLReadDisplayView(CHTMLReadDisplay* display, QWidget* parent); + /** + * Reimplementation from QScrollView. Sets the right slots + */ + virtual void polish(); + /** + * Reimplementatiob from QScrollView. + */ + virtual void contentsDropEvent( QDropEvent* ); + /** + * Reimplementatiob from QScrollView. + */ + virtual void contentsDragEnterEvent( QDragEnterEvent* ); + +protected slots: // Protected slots + /** + * Opens the popupmenu at the given position. + */ + void popupMenu( const QString&, const QPoint& ); + +private: + CHTMLReadDisplay* m_display; +}; + +#endif diff --git a/bibletime/frontend/display/chtmlwritedisplay.cpp b/bibletime/frontend/display/chtmlwritedisplay.cpp new file mode 100644 index 0000000..e535f26 --- /dev/null +++ b/bibletime/frontend/display/chtmlwritedisplay.cpp @@ -0,0 +1,266 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2006 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + + +#include "chtmlwritedisplay.h" + +#include "frontend/displaywindow/cwritewindow.h" + +#include "util/cresmgr.h" + +//Qt includes +#include <qpopupmenu.h> +#include <qtooltip.h> + +//KDE includes +#include <kaction.h> +#include <ktoolbar.h> +#include <klocale.h> +#include <kfontcombo.h> +#include <kcolorbutton.h> +#include <kpopupmenu.h> + +CHTMLWriteDisplay::CHTMLWriteDisplay(CWriteWindow* parentWindow, QWidget* parent) +: CPlainWriteDisplay(parentWindow,parent) { + m_actions.bold = 0; + m_actions.italic = 0; + m_actions.underline = 0; + m_actions.selectAll = 0; + + setTextFormat(Qt::RichText); + setAcceptDrops(true); + viewport()->setAcceptDrops(true); +} + +CHTMLWriteDisplay::~CHTMLWriteDisplay() {} + +void CHTMLWriteDisplay::setText( const QString& newText ) { + QString text = newText; +// text.replace("\n<br/><!-- BT newline -->\n", "\n"); + + QTextEdit::setText(text); +} + +const QString CHTMLWriteDisplay::plainText() { + return QTextEdit::text(); +}; + +void CHTMLWriteDisplay::toggleBold() { + setBold( m_actions.bold->isChecked() ); +}; + +void CHTMLWriteDisplay::toggleItalic() { + setItalic( m_actions.italic->isChecked() ); +}; + +void CHTMLWriteDisplay::toggleUnderline() { + setUnderline( m_actions.underline->isChecked() ); +}; + + +void CHTMLWriteDisplay::alignLeft() { + setAlignment(Qt::AlignLeft); +}; + +void CHTMLWriteDisplay::alignCenter() { + setAlignment(Qt::AlignHCenter); +}; + +void CHTMLWriteDisplay::alignRight() { + setAlignment(Qt::AlignRight); +}; + + +/** The text's alignment changed. Enable the right buttons. */ +void CHTMLWriteDisplay::slotAlignmentChanged( int a ) { + bool alignLeft = false; + bool alignCenter = false; + bool alignRight = false; + // bool alignJustify = false; + + if (a & Qt::AlignLeft) { + alignLeft = true; + } + else if ((a & Qt::AlignHCenter) || (a & Qt::AlignCenter)) { + alignCenter = true; + } + else if (a & Qt::AlignRight) { + alignRight = true; + } + // else if (a & Qt::AlignJustify) { + // alignJustify = true; + // } + else { + alignLeft = true; + qWarning("unknown alignment %i", a); + } + + m_actions.alignLeft->setChecked( alignLeft ); + m_actions.alignCenter->setChecked( alignCenter ); + m_actions.alignRight->setChecked( alignRight ); + // m_actions.alignJustify->setChecked( alignJustify ); +} + + +/** Is called when a new color was selected. */ +void CHTMLWriteDisplay::slotColorSelected( const QColor& c) { + setColor( c ); +} + +/** Is called when a text with another color was selected. */ +void CHTMLWriteDisplay::slotColorChanged(const QColor& c) { + m_colorButton->setColor(c); +} + + +void CHTMLWriteDisplay::slotFontChanged( const QFont& font ) { + m_actions.fontChooser->setFont( font.family() ); + m_actions.fontSizeChooser->setFontSize( font.pointSize() ); + + m_actions.bold->setChecked( font.bold() ); + m_actions.italic->setChecked( font.italic() ); + m_actions.underline->setChecked( font.underline() ); +}; + +void CHTMLWriteDisplay::setupToolbar(KToolBar * bar, KActionCollection * actions) { + m_actions.fontChooser = new KFontAction( i18n("Choose a font"), + CResMgr::displaywindows::writeWindow::underlinedText::accel, + actions, + CResMgr::displaywindows::writeWindow::fontFamily::actionName + ); + m_actions.fontChooser->setToolTip( CResMgr::displaywindows::writeWindow::fontFamily::tooltip ); + + m_actions.fontChooser->plug(bar); + connect(m_actions.fontChooser, SIGNAL(activated(const QString&)), this, SLOT(setFamily(const QString&))); + + + m_actions.fontSizeChooser = new KFontSizeAction( i18n("Choose a font size"), + CResMgr::displaywindows::writeWindow::fontSize::accel, + actions, + CResMgr::displaywindows::writeWindow::fontSize::actionName + ); + m_actions.fontSizeChooser->setToolTip( CResMgr::displaywindows::writeWindow::fontSize::tooltip ); + + m_actions.fontSizeChooser->plug(bar); + connect(m_actions.fontSizeChooser, SIGNAL(fontSizeChanged(int)), this, SLOT(setPointSize(int))); + + m_colorButton = new KColorButton(bar); + connect(m_colorButton, SIGNAL(changed(const QColor&)), this, SLOT(slotColorSelected(const QColor&))); + bar->insertWidget(50, m_colorButton->sizeHint().width(), m_colorButton); + QToolTip::add + (m_colorButton, CResMgr::displaywindows::writeWindow::fontColor::tooltip ); + + + + (new KActionSeparator())->plug(bar); //seperate font options from formatting buttons + + m_actions.bold = new KToggleAction( i18n("Bold"), + CResMgr::displaywindows::writeWindow::boldText::icon, + CResMgr::displaywindows::writeWindow::boldText::accel, + this, SLOT(toggleBold()), + actions, + CResMgr::displaywindows::writeWindow::boldText::actionName + ); + m_actions.bold->setToolTip( CResMgr::displaywindows::writeWindow::boldText::tooltip ); + + m_actions.bold->plug(bar); + + m_actions.italic = new KToggleAction( i18n("Italic"), + CResMgr::displaywindows::writeWindow::italicText::icon, + CResMgr::displaywindows::writeWindow::italicText::accel, + this, SLOT(toggleItalic()), + actions, + CResMgr::displaywindows::writeWindow::italicText::actionName + ); + m_actions.italic->setToolTip( CResMgr::displaywindows::writeWindow::italicText::tooltip ); + + m_actions.italic->plug(bar); + + m_actions.underline = new KToggleAction( i18n("Underline"), + CResMgr::displaywindows::writeWindow::underlinedText::icon, + CResMgr::displaywindows::writeWindow::underlinedText::accel, + this, SLOT(toggleUnderline()), + actions, + CResMgr::displaywindows::writeWindow::underlinedText::actionName + ); + m_actions.underline->setToolTip( CResMgr::displaywindows::writeWindow::underlinedText::tooltip ); + + m_actions.underline->plug(bar); + + + (new KActionSeparator())->plug(bar); //seperate formatting from alignment buttons + + m_actions.alignLeft = new KToggleAction( i18n("Left"), + CResMgr::displaywindows::writeWindow::alignLeft::icon, + CResMgr::displaywindows::writeWindow::alignLeft::accel, + this, SLOT( alignLeft() ), + actions, + CResMgr::displaywindows::writeWindow::alignLeft::actionName + ); + m_actions.alignLeft->setToolTip( CResMgr::displaywindows::writeWindow::alignLeft::tooltip ); + + m_actions.alignLeft->plug(bar); + + m_actions.alignCenter = new KToggleAction( i18n("Center"), + CResMgr::displaywindows::writeWindow::alignCenter::icon, + CResMgr::displaywindows::writeWindow::alignCenter::accel, + this, SLOT(alignCenter()), + actions, + CResMgr::displaywindows::writeWindow::alignCenter::actionName + ); + m_actions.alignCenter->setToolTip( CResMgr::displaywindows::writeWindow::alignCenter::tooltip ); + + m_actions.alignCenter->plug(bar); + + m_actions.alignRight = new KToggleAction( i18n("Right"), + CResMgr::displaywindows::writeWindow::alignRight::icon, + CResMgr::displaywindows::writeWindow::alignRight::accel, + this, SLOT(alignRight()), + actions, + CResMgr::displaywindows::writeWindow::alignRight::actionName + ); + m_actions.alignRight->setToolTip( CResMgr::displaywindows::writeWindow::alignRight::tooltip ); + + m_actions.alignRight->plug(bar); + + // m_actions.alignJustify = new KToggleAction( i18n("Justify"), + // CResMgr::displaywindows::writeWindow::alignJustify::icon, + // CResMgr::displaywindows::writeWindow::alignJustify::accel, + // this, SLOT( alignJustify() ), + // actions + // ); + // m_actions.alignJustify->setToolTip( CResMgr::displaywindows::writeWindow::alignJustify::tooltip ); + + // m_actions.alignJustify->plug(bar); + + + connect(this, SIGNAL(currentFontChanged(const QFont&)), SLOT(slotFontChanged(const QFont&))); + connect(this, SIGNAL(currentAlignmentChanged(int)), SLOT(slotAlignmentChanged(int))); + connect(this, SIGNAL(currentColorChanged(const QColor&)), SLOT(slotColorChanged(const QColor&))); + + + //set initial values for toolbar items + slotFontChanged( font() ); + slotAlignmentChanged( alignment() ); + slotColorChanged( color() ); +} + +/** Reimplementation to show a popup menu if the right mouse butoon was clicked. */ +QPopupMenu* CHTMLWriteDisplay::createPopupMenu( const QPoint& /*pos*/ ) { + if (!m_actions.selectAll) { + m_actions.selectAll = new KAction(i18n("Select all"), KShortcut(0), this, SLOT(selectAll()), this); + } + + KPopupMenu* popup = new KPopupMenu(this); + popup->insertTitle(i18n("HTML editor window")); + m_actions.selectAll->plug(popup); + + return popup; +}; diff --git a/bibletime/frontend/display/chtmlwritedisplay.h b/bibletime/frontend/display/chtmlwritedisplay.h new file mode 100644 index 0000000..ad5faa6 --- /dev/null +++ b/bibletime/frontend/display/chtmlwritedisplay.h @@ -0,0 +1,104 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2006 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + + +#ifndef CHTMLWRITEDISPLAY_H +#define CHTMLWRITEDISPLAY_H + +//BibleTime includes +#include "cplainwritedisplay.h" + +//Qt includes +#include <qwidget.h> +#include <qtextedit.h> + +class CWriteWindow; + +class QPopupMenu; + +class KToggleAction; +class KFontAction; +class KFontSizeAction; + +class KColorButton; + +/** The WYSIWYG implementation of the write display interface. + * @author The BibleTime team + */ +class CHTMLWriteDisplay : public CPlainWriteDisplay { + Q_OBJECT +public: + /** + * Sets the new text for this display widget. + */ + virtual void setText( const QString& newText ); + /** + * Returns the text of this edit widget. + */ + virtual const QString plainText(); + + /** + * Creates the necessary action objects and puts them on the toolbar. + */ + virtual void setupToolbar(KToolBar * bar, KActionCollection * actionCollection); + +protected: + friend class CDisplay; + CHTMLWriteDisplay(CWriteWindow* parentWindow, QWidget* parent); + ~CHTMLWriteDisplay(); + /** + * Reimplementation to show a popup menu if the right mouse butoon was clicked. + */ + virtual QPopupMenu* createPopupMenu( const QPoint& pos ); + +protected slots: + void toggleBold(); + void toggleItalic(); + void toggleUnderline(); + + void alignLeft(); + void alignCenter(); + void alignRight(); + + void slotFontChanged( const QFont& ); + /** + * The text's alignment changed. Enable the right buttons. + */ + void slotAlignmentChanged( int ); + /** + * Is called when a new color was selected. + */ + void slotColorSelected( const QColor& ); + /** + * Is called when a text with another color was selected. + */ + void slotColorChanged( const QColor& ); + +private: + struct { + KToggleAction* bold; + KToggleAction* italic; + KToggleAction* underline; + + KToggleAction* alignLeft; + KToggleAction* alignCenter; + KToggleAction* alignRight; + + KFontAction* fontChooser; + KFontSizeAction* fontSizeChooser; + + //popup menu + KAction* selectAll; + } + m_actions; + KColorButton* m_colorButton; +}; + +#endif diff --git a/bibletime/frontend/display/cplainwritedisplay.cpp b/bibletime/frontend/display/cplainwritedisplay.cpp new file mode 100644 index 0000000..2e81db0 --- /dev/null +++ b/bibletime/frontend/display/cplainwritedisplay.cpp @@ -0,0 +1,157 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2006 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + + +#include "cplainwritedisplay.h" + +#include "frontend/cdragdropmgr.h" +#include "frontend/displaywindow/cdisplaywindow.h" +#include "frontend/displaywindow/cwritewindow.h" + +#include "util/scoped_resource.h" + +//Qt includes + +//KDE includes +#include <kaction.h> +#include <klocale.h> + +CPlainWriteDisplay::CPlainWriteDisplay(CWriteWindow* parentWindow, QWidget* parent) : QTextEdit(parentWindow ? parentWindow : parent), CWriteDisplay(parentWindow) { + setTextFormat(Qt::PlainText); + setAcceptDrops(true); + viewport()->setAcceptDrops(true); + + connect(this, SIGNAL(textChanged()), + connectionsProxy(), SLOT(emitTextChanged())); +} + +CPlainWriteDisplay::~CPlainWriteDisplay() {} + +/** Reimplementation. */ +void CPlainWriteDisplay::selectAll() { + QTextEdit::selectAll(true); +} + +void CPlainWriteDisplay::setText( const QString& newText ) { + //make sure the text has been converted to show \n instead of <br/> + QString text = newText; +// text.replace("\n<br /><!-- BT newline -->\n", "\n"); + text.replace("<br />", "\n"); //inserted by BT or the Qt textedit widget + + QTextEdit::setText(text); +} + +const bool CPlainWriteDisplay::hasSelection() { + return hasSelectedText(); +} + +QWidget* CPlainWriteDisplay::view() { + qDebug("CPlainWriteDisplay::view()"); + return this; +} + +const QString CPlainWriteDisplay::text( const CDisplay::TextType /*format*/, const CDisplay::TextPart /*part*/) { + return QString::null; +} + +void CPlainWriteDisplay::print( const CDisplay::TextPart, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions ) { +} + +/** Sets the current status of the edit widget. */ +void CPlainWriteDisplay::setModified( const bool modified ) { + QTextEdit::setModified(modified); +} + +/** Reimplementation. */ +const bool CPlainWriteDisplay::isModified() const { + return QTextEdit::isModified(); +} + + +/** Returns the text of this edit widget. */ +const QString CPlainWriteDisplay::plainText() { + QString ret = QTextEdit::text(); + + //in plain text mode the text just contains newlines, convert them into <br/> before we return the text for display in a HTML widget + ret.replace("\n", "<br />"); + + return ret; +} + +/** Reimplementation from QTextEdit. Provides an popup menu for the given position. */ +QPopupMenu* CPlainWriteDisplay::createPopupMenu( const QPoint& /*pos*/ ) { + return installedPopup(); +} + +/** Reimplementation from QTextEdit. Provides an popup menu for the given position. */ +QPopupMenu* CPlainWriteDisplay::createPopupMenu( ) { + return installedPopup(); +} + +/** Creates the necessary action objects and puts them on the toolbar. */ +void CPlainWriteDisplay::setupToolbar(KToolBar* /*bar*/, KActionCollection* /*actionCollection*/) {} + +/** Reimplementation to insert the text of a dragged reference into the edit view. */ +void CPlainWriteDisplay::contentsDragEnterEvent( QDragEnterEvent* e ) { + if (CDragDropMgr::canDecode(e)) { + e->accept(true); + } + else { + e->accept(false); + e->ignore(); + } +} + +/** Reimplementation to insert the text of a dragged reference into the edit view. */ +void CPlainWriteDisplay::contentsDragMoveEvent( QDragMoveEvent* e ) { + if (CDragDropMgr::canDecode(e)) { + placeCursor(e->pos()); + ensureCursorVisible(); + e->accept(true); + } + else { + e->accept(false); + e->ignore(); + } +} + +/** Reimplementation to manage drops of our drag and drop objects. */ +void CPlainWriteDisplay::contentsDropEvent( QDropEvent* e ) { + if ( CDragDropMgr::canDecode(e) ) { + e->acceptAction(); + + CDragDropMgr::ItemList items = CDragDropMgr::decode(e); + CDragDropMgr::ItemList::iterator it; + for (it = items.begin(); it != items.end(); ++it) { + switch ((*it).type()) { + case CDragDropMgr::Item::Bookmark: { + CSwordModuleInfo* module = backend()->findModuleByName((*it).bookmarkModule()); + util::scoped_ptr<CSwordKey> key( CSwordKey::createInstance(module) ); + key->key( (*it).bookmarkKey() ); + + QString moduleText = key->strippedText(); + + const QString text = QString::fromLatin1("%1\n(%2, %3)\n").arg(moduleText).arg((*it).bookmarkKey()).arg((*it).bookmarkModule()); + + placeCursor( e->pos() ); + insert( text ); + break; + } + case CDragDropMgr::Item::Text: { + placeCursor( e->pos() ); + insert( (*it).text() ); + break; + } + default: + break; + } + } + } +} diff --git a/bibletime/frontend/display/cplainwritedisplay.h b/bibletime/frontend/display/cplainwritedisplay.h new file mode 100644 index 0000000..9219578 --- /dev/null +++ b/bibletime/frontend/display/cplainwritedisplay.h @@ -0,0 +1,94 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2006 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + + +#ifndef CPLAINWRITEDISPLAY_H +#define CPLAINWRITEDISPLAY_H + +//Bibletime include files +#include "cwritedisplay.h" + +//Qt includes +#include <qwidget.h> +#include <qtextedit.h> + +class CHTMLWriteDisplay; +class KAction; + +/** The write display implementation for plain source code editing. + * @author The BibleTime team + */ +class CPlainWriteDisplay : public QTextEdit, public CWriteDisplay { +public: + /** + * Reimplementation. + */ + virtual void selectAll(); + /** + * Sets the new text for this display widget. + */ + virtual void setText( const QString& newText ); + /** + * Returns true if the display widget has a selection. Otherwise false. + */ + virtual const bool hasSelection(); + /** + * Returns the view of this display widget. + */ + virtual QWidget* view(); + virtual const QString text( const CDisplay::TextType format = CDisplay::HTMLText, const CDisplay::TextPart part = CDisplay::Document ); + virtual void print( const CDisplay::TextPart, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions ); + /** + * Reimplementation. + */ + virtual const bool isModified() const; + /** + * Sets the current status of the edit widget. + */ + virtual void setModified( const bool modified ); + /** + * Returns the text of this edit widget. + */ + virtual const QString plainText(); + /** + * Creates the necessary action objects and puts them on the toolbar. + */ + virtual void setupToolbar(KToolBar * bar, KActionCollection * actionCollection); + +protected: + friend class CDisplay; + friend class CHTMLWriteDisplay; + + CPlainWriteDisplay(CWriteWindow* parentWindow, QWidget* parent); + virtual ~CPlainWriteDisplay(); + /** + * Reimplementation from QTextEdit. Provides an popup menu for the given position. + */ + virtual QPopupMenu* createPopupMenu( const QPoint& pos ); + /** + * Reimplementation from QTextEdit. Provides an popup menu. + */ + virtual QPopupMenu* createPopupMenu(); + /** + * Reimplementation to manage drops of our drag and drop objects. + */ + virtual void contentsDropEvent( QDropEvent* e ); + /** + * Reimplementation to insert the text of a dragged reference into the edit view. + */ + virtual void contentsDragEnterEvent( QDragEnterEvent* e ); + /** + * Reimplementation to insert the text of a dragged reference into the edit view. + */ + virtual void contentsDragMoveEvent( QDragMoveEvent* e ); + +}; + +#endif diff --git a/bibletime/frontend/display/creaddisplay.cpp b/bibletime/frontend/display/creaddisplay.cpp new file mode 100644 index 0000000..24c4f76 --- /dev/null +++ b/bibletime/frontend/display/creaddisplay.cpp @@ -0,0 +1,115 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2006 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + + +//BibleTime includes +#include "creaddisplay.h" + +#include "backend/cswordmoduleinfo.h" +#include "backend/cswordbiblemoduleinfo.h" +#include "backend/cswordlexiconmoduleinfo.h" +#include "backend/cswordbookmoduleinfo.h" +#include "backend/cswordkey.h" +#include "backend/cswordversekey.h" +#include "backend/cswordtreekey.h" +#include "backend/cswordldkey.h" + +#include "frontend/displaywindow/cdisplaywindow.h" +#include "frontend/displaywindow/creadwindow.h" + +#include "frontend/cexportmanager.h" + +#include "util/scoped_resource.h" + +//Qt includes +#include <qpopupmenu.h> + +//KDE includes +#include <klocale.h> + +CReadDisplay::CReadDisplay(CReadWindow* readWindow) : +CDisplay(readWindow), +m_activeAnchor(QString::null), +m_useMouseTracking(true) {} + +CReadDisplay::~CReadDisplay() {} + +/** Returns the current active anchor. */ +const QString& CReadDisplay::activeAnchor() { + return m_activeAnchor; +} + +/** Sets the current anchor to the parameter. */ +void CReadDisplay::setActiveAnchor( const QString& anchor ) { + m_activeAnchor = anchor; +} + + +/** Returns true if the display has an active anchor. */ +const bool CReadDisplay::hasActiveAnchor() { + return !activeAnchor().isEmpty(); +} + + +void CReadDisplay::print(const CDisplay::TextPart type, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) { + CDisplayWindow* window = parentWindow(); + CSwordKey* const key = window->key(); + CSwordModuleInfo* module = key->module(); + + + CExportManager mgr(i18n("Print keys"),false, QString::null, parentWindow()->filterOptions(), parentWindow()->displayOptions()); + + switch (type) { + case Document: { + if (module->type() == CSwordModuleInfo::Bible) { + CSwordVerseKey* vk = dynamic_cast<CSwordVerseKey*>(key); + + CSwordVerseKey startKey(*vk); + startKey.Verse(1); + + CSwordVerseKey stopKey(*vk); + + CSwordBibleModuleInfo* bible = dynamic_cast<CSwordBibleModuleInfo*>(module); + if (bible) { + stopKey.Verse( bible->verseCount( bible->bookNumber(startKey.book()), startKey.Chapter() ) ); + } + + mgr.printKey(module, startKey.key(), stopKey.key(), displayOptions, filterOptions); + } + else if (module->type() == CSwordModuleInfo::Lexicon || module->type() == CSwordModuleInfo::Commentary ) { + mgr.printKey(module, key->key(), key->key(), displayOptions, filterOptions); + } + else if (module->type() == CSwordModuleInfo::GenericBook) { + CSwordTreeKey* tree = dynamic_cast<CSwordTreeKey*>(key); + + CSwordTreeKey startKey(*tree); + // while (startKey.previousSibling()) { // go to first sibling on this level! + // } + + CSwordTreeKey stopKey(*tree); + // if (CSwordBookModuleInfo* book = dynamic_cast<CSwordBookModuleInfo*>(module)) { + // while ( stopKey.nextSibling() ) { //go to last displayed sibling! + // } + // } + mgr.printKey(module, startKey.key(), stopKey.key(), displayOptions, filterOptions); + } + } + + case AnchorWithText: { + if (hasActiveAnchor()) { + mgr.printByHyperlink( activeAnchor(), displayOptions, filterOptions ); + } + } + + default: + break; + } +} + diff --git a/bibletime/frontend/display/creaddisplay.h b/bibletime/frontend/display/creaddisplay.h new file mode 100644 index 0000000..de3e51d --- /dev/null +++ b/bibletime/frontend/display/creaddisplay.h @@ -0,0 +1,71 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2006 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + + +#ifndef CREADDISPLAY_H +#define CREADDISPLAY_H + +#include "cdisplay.h" +#include "backend/cswordbackend.h" + +class QPopupMenu; +class QWidget; + +/**The base class for all read-only widgets like KHTMLView. + *@author The BibleTime team + */ + +class CReadDisplay : public CDisplay { +public: + /** + * Returns true if the display has an active anchor. + */ + const bool hasActiveAnchor(); + /** + * Returns the current active anchor. + */ + const QString& activeAnchor(); + /** + * Moves the widget to the given anchor. + */ + virtual void moveToAnchor( const QString& ) = 0; + virtual void print(const CDisplay::TextPart, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions); + + void setMouseTracking(const bool trackingEnabled) { + m_useMouseTracking = trackingEnabled; + }; + const bool getMouseTracking() const { + return m_useMouseTracking; + }; + +protected: // Protected methods + friend class CDisplay; + friend class CHTMLReadDisplay; + friend class CHTMLReadDisplayView; + + CReadDisplay( CReadWindow* readWindow ); + ~CReadDisplay(); + + /** + * Sets the current anchor to the parameter. + */ + void setActiveAnchor( const QString& ); + +private: // Public attributes + /** + * The member which hols the current anchor. + */ + + QString m_activeAnchor; + + bool m_useMouseTracking; +}; + +#endif diff --git a/bibletime/frontend/display/cwritedisplay.cpp b/bibletime/frontend/display/cwritedisplay.cpp new file mode 100644 index 0000000..1c3ad4e --- /dev/null +++ b/bibletime/frontend/display/cwritedisplay.cpp @@ -0,0 +1,23 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2006 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + + +//BibleTime includes +#include "cwritedisplay.h" + +#include "frontend/displaywindow/cwritewindow.h" + +//Qt includes +#include <qwidget.h> + +CWriteDisplay::CWriteDisplay( CWriteWindow* writeWindow ) : CDisplay(writeWindow) {} + +CWriteDisplay::~CWriteDisplay() {} + diff --git a/bibletime/frontend/display/cwritedisplay.h b/bibletime/frontend/display/cwritedisplay.h new file mode 100644 index 0000000..b1222e8 --- /dev/null +++ b/bibletime/frontend/display/cwritedisplay.h @@ -0,0 +1,50 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2006 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + + +#ifndef CWRITEDISPLAY_H +#define CWRITEDISPLAY_H + +#include "cdisplay.h" + +class KActionCollection; +class KToolBar; + +/**The base class for all read/write-display classes. + *@author The BibleTime team + */ + +class CWriteDisplay : public CDisplay { +protected: + friend class CDisplay; + friend class CPlainWriteDisplay; + CWriteDisplay( CWriteWindow* writeWindow ); + ~CWriteDisplay(); + +public: // Public methods + /** + * Sets the current modified status of the widget. + */ + virtual void setModified( const bool modified ) = 0; + /** + * Returns true if the current text was modified. + */ + virtual const bool isModified() const = 0; + /** + * Returns the text of this edit widget. + */ + virtual const QString plainText() = 0; + /** + * Creates the necessary action objects and puts them on the toolbar. + */ + virtual void setupToolbar( KToolBar* bar, KActionCollection* actionCollection ) = 0; +}; + +#endif |