diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 00bb99ac80741fc50ef8a289719373032f2391eb (patch) | |
tree | 3a5a9bf72f942784b38bf77dd66c534662fab5f2 /ksayit/src | |
download | tdeaccessibility-00bb99ac80741fc50ef8a289719373032f2391eb.tar.gz tdeaccessibility-00bb99ac80741fc50ef8a289719373032f2391eb.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeaccessibility@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'ksayit/src')
47 files changed, 9499 insertions, 0 deletions
diff --git a/ksayit/src/ContextMenus.xml b/ksayit/src/ContextMenus.xml new file mode 100644 index 0000000..201e8ec --- /dev/null +++ b/ksayit/src/ContextMenus.xml @@ -0,0 +1,100 @@ +<?xml version = '1.0' encoding = 'ISO-8859-1'?> +<KSayItContextActions> + <Item editable="no" id="RobDocument"> + <Submenu name="New"> + <Action qty="1">BookInfo</Action> + <Action qty="n">Chapter</Action> + </Submenu> + </Item> + <Item editable="no" id="BookInfo"> + <Submenu name="New"> + <Action qty="1">KeywordSet</Action> + <Action qty="1">Abstract</Action> + <Action qty="1">AuthorGroup</Action> + <Action qty="1">Date</Action> + <Action qty="1">ReleaseInfo</Action> + </Submenu> + <Action qty="n">Delete</Action> + </Item> + <Item editable="no" id="AuthorGroup"> + <Submenu name="New"> + <Action qty="n">Author</Action> + </Submenu> + <Action qty="n">Rename</Action> + <Action qty="n">Delete</Action> + </Item> + <Item editable="no" id="KeywordSet"> + <Submenu name="New"> + <Action qty="n">Keyword</Action> + </Submenu> + <Action qty="n">Delete</Action> + </Item> + <Item editable="yes" maxlines="1" id="Keyword"> + <Action qty="n">Delete</Action> + </Item> + <Item editable="yes" maxlines="1" id="Author"> + <Action qty="n">Delete</Action> + </Item> + <Item editable="yes" maxlines="1" id="Date"> + <Action qty="n">Delete</Action> + </Item> + <Item editable="yes" maxlines="1" id="ReleaseInfo"> + <Action qty="n">Delete</Action> + </Item> + <Item editable="no" id="Abstract"> + <Submenu name="New"> + <Action qty="n">Paragraph</Action> + </Submenu> + <Action qty="n">Delete</Action> + </Item> + <Item editable="no" id="Chapter"> + <Submenu name="New"> + <Action qty="n">Paragraph</Action> + <Action qty="n">Section_1</Action> + </Submenu> + <Action qty="n">Rename</Action> + <Action qty="n">Delete</Action> + </Item> + <Item editable="no" id="Sect1"> + <Submenu name="New"> + <Action qty="n">Paragraph</Action> + <Action qty="n">Section_2</Action> + </Submenu> + <Action qty="n">Rename</Action> + <Action qty="n">Delete</Action> + </Item> + <Item editable="no" id="Sect2"> + <Submenu name="New"> + <Action qty="n">Paragraph</Action> + <Action qty="n">Section_3</Action> + </Submenu> + <Action qty="n">Rename</Action> + <Action qty="n">Delete</Action> + </Item> + <Item editable="no" id="Sect3"> + <Submenu name="New"> + <Action qty="n">Paragraph</Action> + <Action qty="n">Section_4</Action> + </Submenu> + <Action qty="n">Rename</Action> + <Action qty="n">Delete</Action> + </Item> + <Item editable="no" id="Sect4"> + <Submenu name="New"> + <Action qty="n">Paragraph</Action> + <Action qty="n">Section_5</Action> + </Submenu> + <Action qty="n">Rename</Action> + <Action qty="n">Delete</Action> + </Item> + <Item editable="no" id="Sect5"> + <Submenu name="New"> + <Action qty="n">Paragraph</Action> + </Submenu> + <Action qty="n">Rename</Action> + <Action qty="n">Delete</Action> + </Item> + <Item editable="yes" maxlines="-1" id="Para"> + <Action qty="n">Delete</Action> + </Item> +</KSayItContextActions> diff --git a/ksayit/src/DocTreeView.ui b/ksayit/src/DocTreeView.ui new file mode 100644 index 0000000..14e5f09 --- /dev/null +++ b/ksayit/src/DocTreeView.ui @@ -0,0 +1,158 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>DocTreeView</class> +<widget class="QWidget"> + <property name="name"> + <cstring>DocTreeView</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>467</width> + <height>331</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>200</height> + </size> + </property> + <property name="caption"> + <string>Document Contents</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>2</number> + </property> + <property name="resizeMode"> + <enum>Minimum</enum> + </property> + <widget class="KListView" row="0" column="0"> + <column> + <property name="text"> + <string>Chapter</string> + </property> + <property name="clickable"> + <bool>false</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Info</string> + </property> + <property name="clickable"> + <bool>false</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Page</string> + </property> + <property name="clickable"> + <bool>false</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Hidden</string> + </property> + <property name="clickable"> + <bool>false</bool> + </property> + <property name="resizable"> + <bool>false</bool> + </property> + </column> + <property name="name"> + <cstring>listView</cstring> + </property> + <property name="resizePolicy"> + <enum>Default</enum> + </property> + <property name="selectionMode" stdset="0"> + <enum>NoSelection</enum> + </property> + <property name="rootIsDecorated"> + <bool>true</bool> + </property> + <property name="itemsMovable"> + <bool>false</bool> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>listView</sender> + <signal>clicked(QListViewItem*)</signal> + <receiver>DocTreeView</receiver> + <slot>slotItemClicked(QListViewItem*)</slot> + </connection> + <connection> + <sender>listView</sender> + <signal>rightButtonPressed(QListViewItem*,const QPoint&,int)</signal> + <receiver>DocTreeView</receiver> + <slot>slotRightButtonPressed(QListViewItem*,const QPoint&,int)</slot> + </connection> +</connections> +<includes> + <include location="local" impldecl="in implementation">DocTreeView.ui.h</include> +</includes> +<signals> + <signal>signalContentChanged(const QString &)</signal> + <signal>signalAllNodesProcessed()</signal> + <signal>signalSetText(const QString &)</signal> + <signal>signalEnableTextedit(bool)</signal> + <signal>signalNotifyBookmarkManager(const QString&, const QString &)</signal> + <signal>signalSetBookmarkFilename(const QString&)</signal> + <signal>signalChangeBookmarkFilename(const QString &)</signal> + <signal>signalDeleteBookmark(const QString&, const QString&)</signal> +</signals> +<slots> + <slot>slotItemClicked( QListViewItem * )</slot> + <slot access="protected">slotRenameItem()</slot> + <slot access="protected">slotDeleteItem()</slot> + <slot access="protected">slotNewBookInfo()</slot> + <slot access="protected">slotNewChapter()</slot> + <slot access="protected">slotNewKeywordSet()</slot> + <slot access="protected">slotNewKeyword()</slot> + <slot access="protected">slotNewAbstract()</slot> + <slot access="protected">slotNewAuthorGroup()</slot> + <slot access="protected">slotNewAuthor()</slot> + <slot access="protected">slotNewDate()</slot> + <slot access="protected">slotNewReleaseInfo()</slot> + <slot access="protected">slotNewTitle()</slot> + <slot access="protected">slotNewParagraph()</slot> + <slot access="protected">slotNewSection_1()</slot> + <slot access="protected">slotNewSection_2()</slot> + <slot access="protected">slotNewSection_3()</slot> + <slot access="protected">slotNewSection_4()</slot> + <slot access="protected">slotNewSection_5()</slot> + <slot>slotRightButtonPressed( QListViewItem * i, const QPoint &, int )</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/ksayit/src/DocTreeView.ui.h b/ksayit/src/DocTreeView.ui.h new file mode 100644 index 0000000..39720c1 --- /dev/null +++ b/ksayit/src/DocTreeView.ui.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you want to add, delete, or rename functions or slots, use +** Qt Designer to update this file, preserving your code. +** +** You should not define a constructor or destructor in this file. +** Instead, write your code in functions called init() and destroy(). +** These will automatically be called by the form's constructor and +** destructor. +*****************************************************************************/ + + +void DocTreeView::slotItemClicked( QListViewItem * ) +{ + +} + + + +void DocTreeView::slotRenameItem() +{ + +} + + +void DocTreeView::slotDeleteItem() +{ + +} + + +void DocTreeView::slotNewBookInfo() +{ + +} + + +void DocTreeView::slotNewChapter() +{ + +} + + +void DocTreeView::slotNewKeywordSet() +{ + +} + + +void DocTreeView::slotNewKeyword() +{ + +} + + +void DocTreeView::slotNewAbstract() +{ + +} + + +void DocTreeView::slotNewAuthorGroup() +{ + +} + + +void DocTreeView::slotNewAuthor() +{ + +} + + +void DocTreeView::slotNewDate() +{ + +} + + +void DocTreeView::slotNewReleaseInfo() +{ + +} + + +void DocTreeView::slotNewTitle() +{ + +} + + +void DocTreeView::slotNewParagraph() +{ + +} + + +void DocTreeView::slotNewSection_1() +{ + +} + + +void DocTreeView::slotNewSection_2() +{ + +} + + +void DocTreeView::slotNewSection_3() +{ + +} + + +void DocTreeView::slotNewSection_4() +{ + +} + + +void DocTreeView::slotNewSection_5() +{ + +} + + +void DocTreeView::slotRightButtonPressed( QListViewItem *i, const QPoint &, int ) +{ + +} diff --git a/ksayit/src/KSayItView.ui b/ksayit/src/KSayItView.ui new file mode 100644 index 0000000..4ffa9b9 --- /dev/null +++ b/ksayit/src/KSayItView.ui @@ -0,0 +1,69 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>KSayItView</class> +<widget class="QWidget"> + <property name="name"> + <cstring>KSayItView</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>422</width> + <height>441</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>2</number> + </property> + <widget class="KTextEdit" row="0" column="0"> + <property name="name"> + <cstring>TextEdit</cstring> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>200</height> + </size> + </property> + <property name="textFormat"> + <enum>RichText</enum> + </property> + <property name="linkUnderline"> + <bool>false</bool> + </property> + <property name="autoFormatting"> + <set>AutoAll</set> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>TextEdit</sender> + <signal>copyAvailable(bool)</signal> + <receiver>KSayItView</receiver> + <slot>slotCopyAvailable(bool)</slot> + </connection> + <connection> + <sender>TextEdit</sender> + <signal>textChanged()</signal> + <receiver>KSayItView</receiver> + <slot>slotTextChanged()</slot> + </connection> +</connections> +<tabstops> + <tabstop>TextEdit</tabstop> +</tabstops> +<slots> + <slot>slotCopyAvailable(bool)</slot> + <slot>slotTextChanged()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>ktextedit.h</includehint> +</includehints> +</UI> diff --git a/ksayit/src/Makefile.am b/ksayit/src/Makefile.am new file mode 100644 index 0000000..9fb2b84 --- /dev/null +++ b/ksayit/src/Makefile.am @@ -0,0 +1,45 @@ +# set the include path for X, qt and KDE +INCLUDES = -I$(top_srcdir)/ksayit/KTTSD_Lib $(all_includes) + +# these are the headers for your project +noinst_HEADERS = doctreeviewimpl.h effectstack.h fxpluginhandler.h \ + fxsetupimpl.h ksayit_fxplugin.h ksayitsystemtray.h ksayit_ttsplugin.h \ + ksayitviewimpl.h Types.h version.h voicesetupdlg.h ksayit.h parasaxparser.h saxhandler.h \ + ksayitbookmarkhandler.h contextmenuhandler.h docbookclasses.h docbookgenerator.h \ + docbookparser.h + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/ksayit.pot + +KDE_ICON = AUTO + + +######################################################################### +# APPLICATION SECTION +######################################################################### +# this is the program that gets installed. it's name is used for all +# of the other Makefile.am variables +bin_PROGRAMS = ksayit + +# the application source, library search path, and link libraries +ksayit_SOURCES = doctreeviewimpl.cpp effectstack.cpp fxpluginhandler.cpp \ + fxsetupimpl.cpp ksayit.skel ksayitsystemtray.cpp ksayitviewimpl.cpp \ + main.cpp voicesetupdlg.cpp ksayit.cpp DocTreeView.ui fx_setup.ui KSayItView.ui \ + parasaxparser.cpp saxhandler.cpp ksayitbookmarkhandler.cpp contextmenuhandler.cpp docbookclasses.cpp \ + docbookgenerator.cpp docbookparser.cpp + +ksayit_LDFLAGS = $(KDE_RPATH) $(all_libraries) +ksayit_LDADD = $(top_builddir)/ksayit/KTTSD_Lib/libKTTSD_Lib.la $(LIB_KIO) \ + -lartskde -lsoundserver_idl -lartsflow + + +# this is where the shell's XML-GUI resource file goes +shellrcdir = $(kde_datadir)/ksayit + + +shellrc_DATA = ksayitui.rc ContextMenus.xml +xdg_apps_DATA = ksayit.desktop +include_HEADERS = ksayit_fxplugin.h diff --git a/ksayit/src/Types.h b/ksayit/src/Types.h new file mode 100644 index 0000000..017f721 --- /dev/null +++ b/ksayit/src/Types.h @@ -0,0 +1,83 @@ +/*************************************************************************** + Types.h - description + ------------------- + begin : Fr Nov 21 2003 + copyright : (C) 2003 by voglrobe + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef TYPES_H +#define TYPES_H + +// #include <vector> + +// QT includes +#include <qvaluelist.h> +#include <qmap.h> + +// KDE includes +#include <klistview.h> + +typedef QValueList<int> ParameterList_type; +typedef QMap<QString, ParameterList_type> EffectConfig_type; + +namespace KSayItGlobal { + static const int item_initial_id = 100; + + enum { + XMLCONTEXTNAME=0, + ISEDITABLE, + MAXLINES, + SUMMARY, + RAWDATA, + RTFHEADER, + RTFDATA, + SPEAKERHEADER, + SPEAKERDATA + }; + +} + +/** +This abstract class is the interface to access the items of the TreeView. +@author Robert Vogl +*/ +class ListViewInterface : public KListViewItem +{ +public: + ListViewInterface(ListViewInterface *parent=0, QString label=QString::null); + ListViewInterface(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ListViewInterface(KListView *lv=0, QString label=QString::null); + + // ~ListViewItemInterface(); + + /** + * Stores data to the item referenced by the given index. + * \param index The index is defined by the following enum: + * \param data The data to store. + * \returns <tt>true</tt> if the operation was successfully performed, + * in all other cases <tt>false</tt>. + */ + virtual bool setValue( unsigned int index, QVariant data ) = 0; + + /** + * Requests data from the item referenced by the index. + * \param index See <tt>setValue()</tt>. + * \returns The requested data as a <tt>QVariant</tt> or a invalid + * <tt>QVariant()</tt> if the data was not available. + */ + virtual QVariant getValue( unsigned int index ) const = 0; + +}; + + +#endif diff --git a/ksayit/src/contextmenuhandler.cpp b/ksayit/src/contextmenuhandler.cpp new file mode 100644 index 0000000..311a39a --- /dev/null +++ b/ksayit/src/contextmenuhandler.cpp @@ -0,0 +1,407 @@ +// +// C++ Implementation: %{MODULE} +// +// Description: +// +// +// Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR} +// +// Copyright: See COPYING file that comes with this distribution +// +// + +// Qt includes +#include <qfile.h> +#include <qvariant.h> + +// KDE includes +#include <kdebug.h> +#include <klocale.h> +#include <kglobal.h> +#include <kstandarddirs.h> + +// App specific includes +#include "Types.h" +#include "contextmenuhandler.h" + + +/** + * XML-ActionHandler + */ +ContextActionHandler::ContextActionHandler(ContextMenuHandler *menuhandler) + : QXmlDefaultHandler(), m_menuhandler(menuhandler) +{ + m_subName = QString::null; + m_actionName = QString::null; + m_qty = QString::null; + m_popup = menuhandler->m_popupmenu; + m_hit = false; + m_searchID = QString::null; +} + +ContextActionHandler::~ContextActionHandler() +{ +} + + +void ContextActionHandler::setSearchID( const QString xmlID ) +{ + m_searchID = xmlID; +} + + +bool ContextActionHandler::startElement( const QString &, + const QString &, + const QString &qName, + const QXmlAttributes &atts ) +{ + if ( qName == "Item" ){ + if ( atts.value("id") == m_searchID ){ + if ( atts.value("editable") == "yes"){ + m_menuhandler->setItemEditable( true ); + } + if ( atts.value("maxlines") != ""){ + m_menuhandler->setItemMaxlines( atts.value("maxlines") ); + } + m_hit = true; + } else { + m_hit = false; + } + } + if ( !(m_hit && m_menuhandler->m_popupmenu) ) + return true; + + if ( qName == "Action" ){ + m_actionName = ""; + m_qty = atts.value("qty"); + } else if ( qName == "Submenu" ){ + if ( atts.value("name") != "" ){ + m_subName = atts.value("name"); + m_popup = m_menuhandler->SubMenuFactory(m_popup); + } + } + return true; +} + + +bool ContextActionHandler::endElement( const QString &, + const QString &, + const QString &qName ) +{ + if ( !(m_hit && m_menuhandler->m_popupmenu) ) + return true; + + if ( qName == "Action" ){ + KAction* newAction = m_menuhandler->ActionFactory(m_actionName, m_qty); + if ( newAction ) + newAction->plug( m_popup ); + } else if ( qName == "Submenu" ){ + if ( m_subName == "New" ){ + m_menuhandler->m_popupmenu->insertItem( i18n("New"), m_popup); + } + // only one sublevel spported -> back to toplevel menu + m_popup = m_menuhandler->m_popupmenu; + } + return true; +} + + +bool ContextActionHandler::characters( const QString &ch ) +{ + m_actionName += ch; + return true; +} + + + +/** + * MenuHandler + */ +ContextMenuHandler::ContextMenuHandler(QObject *parent, const char *name) + : QObject(parent, name), m_DocTreeView(parent) +{ + m_popupmenu = NULL; + m_item = NULL; + initActions(); + m_XmlFilePath = KGlobal::dirs()->findResource("data", "ksayit/ContextMenus.xml"); +} + + +ContextMenuHandler::~ContextMenuHandler() +{ + delete renameItem; + delete deleteItem; + delete newBookInfo; + delete newChapter; + delete newKeywordSet; + delete newKeyword; + delete newAbstract; + delete newAuthorGroup; + delete newAuthor; + delete newDate; + delete newReleaseInfo; + delete newTitle; + delete newParagraph; + delete newSection_1; + delete newSection_2; + delete newSection_3; + delete newSection_4; + delete newSection_5; + + if (m_popupmenu) + delete m_popupmenu; +} + + +void ContextMenuHandler::initActions() +{ + // User defined actions + renameItem = new KAction (i18n("Rename..."), + 0, + m_DocTreeView, SLOT (slotRenameItem()), NULL ); + + deleteItem = new KAction (i18n("Delete..."), + 0, + m_DocTreeView, SLOT (slotDeleteItem()), NULL ); + + newBookInfo = new KAction ( i18n("Overview"), + 0, + m_DocTreeView, SLOT (slotNewBookInfo()), NULL ); + + newChapter = new KAction ( i18n("Chapter"), + 0, + m_DocTreeView, SLOT (slotNewChapter()), NULL ); + + newKeywordSet = new KAction ( i18n("Keywords"), + 0, + m_DocTreeView, SLOT (slotNewKeywordSet()), NULL ); + + newKeyword = new KAction ( i18n("Keyword"), + 0, + m_DocTreeView, SLOT (slotNewKeyword()), NULL ); + + newAbstract = new KAction ( i18n("Abstract"), + 0, + m_DocTreeView, SLOT (slotNewAbstract()), NULL ); + + newAuthorGroup = new KAction ( i18n("Authors"), + 0, + m_DocTreeView, SLOT (slotNewAuthorGroup()), NULL ); + + newAuthor = new KAction ( i18n("Author"), + 0, + m_DocTreeView, SLOT (slotNewAuthor()), NULL ); + + newDate = new KAction ( i18n("Date"), + 0, + m_DocTreeView, SLOT (slotNewDate()), NULL ); + + newReleaseInfo = new KAction ( i18n("Release Info"), + 0, + m_DocTreeView, SLOT (slotNewReleaseInfo()), NULL ); + + newTitle = new KAction ( i18n("Title"), + 0, + m_DocTreeView, SLOT (slotNewTitle()), NULL ); + + newParagraph = new KAction ( i18n("Paragraph"), + 0, + m_DocTreeView, SLOT (slotNewParagraph()), NULL ); + + newSection_1 = new KAction ( i18n("Section Level 1"), + 0, + m_DocTreeView, SLOT (slotNewSection_1()), NULL ); + + newSection_2 = new KAction ( i18n("Section Level 2"), + 0, + m_DocTreeView, SLOT (slotNewSection_2()), NULL ); + + newSection_3 = new KAction ( i18n("Section Level 3"), + 0, + m_DocTreeView, SLOT (slotNewSection_3()), NULL ); + + newSection_4 = new KAction ( i18n("Section Level 4"), + 0, + m_DocTreeView, SLOT (slotNewSection_4()), NULL ); + + newSection_5 = new KAction ( i18n("Section Level 5"), + 0, + m_DocTreeView, SLOT (slotNewSection_5()), NULL ); +} + + +KPopupMenu* ContextMenuHandler::getPopupMenu(ListViewInterface *item) +{ + if ( !item ) + return NULL; + + m_item = item; + + QString xmlID = ( item->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( xmlID.isNull() ) + return NULL; + + // delete old popup menu and create new one + if ( m_popupmenu ){ + delete m_popupmenu; + m_popupmenu = NULL; + } + m_popupmenu = new KPopupMenu(0); + + bool res; + res = parseXmlFile(xmlID); + + if ( res ){ + return m_popupmenu; + } else { + delete m_popupmenu; + m_popupmenu = NULL; + return NULL; + } +} + + +void ContextMenuHandler::registerPopupMenu(ListViewInterface *item) +{ + if ( !item ) + return; + + m_item = item; + + QString xmlID = ( item->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( xmlID.isNull() ) + return; + + // delete old popup menu + if ( m_popupmenu ){ + delete m_popupmenu; + m_popupmenu = NULL; + } + + // if m_popupmenu == NULL, the parser should not create a popupmenu + parseXmlFile(xmlID); +} + + +bool ContextMenuHandler::parseXmlFile(const QString &xmlID) +{ + kdDebug(100200) << "ContextMenuHandler::parseXmlFile()" << endl; + kdDebug(100200) << "XML-File: " << m_XmlFilePath << endl; + + QFile xmlFile( m_XmlFilePath ); + QXmlSimpleReader parser; + ContextActionHandler handler(this); + handler.setSearchID(xmlID); + parser.setContentHandler( &handler ); + return parser.parse( &xmlFile ); +} + + +KAction* ContextMenuHandler::ActionFactory( const QString &actionName, const QString &qty ) +{ + bool enabled; + if ( qty.lower() == "n" ){ + // unlimited don't check return enabled action + enabled = true; + } else { + // check if qty is within allowed limits + ListViewInterface *i = static_cast<ListViewInterface*>(m_item->firstChild()); + int count = 0; + QString name = QString::null; + while (i){ + name = ( i->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( name.lower() == actionName.lower() ){ + count++; + } + i = static_cast<ListViewInterface*>(i->nextSibling()); + } + enabled = count < qty.toInt() ? true : false; + } + + if ( actionName == "Rename" ){ + renameItem->setEnabled( enabled ); + return renameItem; + } else if ( actionName == "Delete" ){ + deleteItem->setEnabled( enabled ); + return deleteItem; + } else if ( actionName == "BookInfo" ){ + newBookInfo->setEnabled( enabled ); + return newBookInfo; + } else if ( actionName == "Chapter" ){ + newChapter->setEnabled( enabled ); + return newChapter; + } else if ( actionName == "KeywordSet" ){ + newKeywordSet->setEnabled( enabled ); + return newKeywordSet; + } else if ( actionName == "Keyword" ){ + newKeyword->setEnabled( enabled ); + return newKeyword; + } else if ( actionName == "Abstract" ){ + newAbstract->setEnabled( enabled ); + return newAbstract; + } else if ( actionName == "AuthorGroup" ){ + newAuthorGroup->setEnabled( enabled ); + return newAuthorGroup; + } else if ( actionName == "Author" ){ + newAuthor->setEnabled( enabled ); + return newAuthor; + } else if ( actionName == "Date" ){ + newDate->setEnabled( enabled ); + return newDate; + } else if ( actionName == "ReleaseInfo" ){ + newReleaseInfo->setEnabled( enabled ); + return newReleaseInfo; + } else if ( actionName == "Title" ){ + newTitle->setEnabled( enabled ); + return newTitle; + } else if ( actionName == "Paragraph" ){ + newParagraph->setEnabled( enabled ); + return newParagraph; + } else if ( actionName == "Section_1" ){ + newSection_1->setEnabled( enabled ); + return newSection_1; + } else if ( actionName == "Section_2" ){ + newSection_2->setEnabled( enabled ); + return newSection_2; + } else if ( actionName == "Section_3" ){ + newSection_3->setEnabled( enabled ); + return newSection_3; + } else if ( actionName == "Section_4" ){ + newSection_4->setEnabled( enabled ); + return newSection_4; + } else if ( actionName == "Section_5" ){ + newSection_5->setEnabled( enabled ); + return newSection_5; + } + kdDebug(100200) << "ERROR!!! ContextMenuHandler::ActionFactory()" << endl; + return NULL; +} + + +KPopupMenu* ContextMenuHandler::SubMenuFactory(KPopupMenu *parent) +{ + return new KPopupMenu(parent); +} + + +void ContextMenuHandler::setItemEditable( bool editable ) +{ + if ( m_item ) + m_item->setValue(KSayItGlobal::ISEDITABLE, editable); +} + + +void ContextMenuHandler::setItemMaxlines( const QString &maxlines ) +{ + if ( maxlines == "" ) + return; + + if ( !m_item ) + return; + + int value = maxlines.toInt(); + m_item->setValue( KSayItGlobal::MAXLINES, value ); +} + + +#include "contextmenuhandler.moc" diff --git a/ksayit/src/contextmenuhandler.h b/ksayit/src/contextmenuhandler.h new file mode 100644 index 0000000..102181a --- /dev/null +++ b/ksayit/src/contextmenuhandler.h @@ -0,0 +1,152 @@ +// +// C++ Interface: %{MODULE} +// +// Description: +// +// +// Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR} +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef CONTEXTMENUHANDLER_H +#define CONTEXTMENUHANDLER_H + +// Qt includes +#include <qobject.h> +#include <qstring.h> +#include <qxml.h> + +// KDE includes +#include <kaction.h> +#include <kpopupmenu.h> + +//forward declarations +class ContextMenuHandler; +class ListViewInterface; + +/** +@author Robert Vogl +*/ +class ContextActionHandler : public QXmlDefaultHandler +{ +public: + ContextActionHandler(ContextMenuHandler *menuhandler = 0); + ~ContextActionHandler(); + + // Reimplementations from base class + bool startElement( const QString &namespaceURI, + const QString &localName, + const QString &qName, + const QXmlAttributes &atts ); + + // Reimplementations from base class + bool endElement( const QString &namespaceURI, + const QString &localName, + const QString &qName ); + + // Reimplementations from base class + bool characters( const QString &ch ); + + void setSearchID( const QString xmlID ); + +private: + ContextMenuHandler *m_menuhandler; + QString m_subName; + QString m_actionName; + QString m_qty; + KPopupMenu *m_popup; + bool m_hit; + QString m_searchID; +}; + + +/** +@author Robert Vogl +*/ +class ContextMenuHandler : public QObject +{ +Q_OBJECT +public: + ContextMenuHandler(QObject *parent = 0, const char *name = 0); + + ~ContextMenuHandler(); + + /** + * \param item The selected TreeView item. + * \returns A pointer to the popup-menu. + */ + KPopupMenu* getPopupMenu(ListViewInterface *item); + + /** + * \returns A pointer to the Submenu as a child of the parent + * \p parent. + */ + KPopupMenu* SubMenuFactory(KPopupMenu *parent); + + /** + * Creates an action sufficiant to the given name. + * It checks if the action is allowed or not and returns + * a disabled or enabled action. + * \param actionName The name of the action as defined in the + * namespace \p ContextMenu.xml. + * \param qty The maximum allowed quantity of the same action for the + * given element. + * \returns A Pointer to the action. + */ + KAction* ActionFactory( const QString &actionName, const QString &qty ); + + /** + * Creates a Popup context menu for the given item and stores a + * pointer to it in \p m_MenuList. + */ + void registerPopupMenu(ListViewInterface *item); + + /** + * Sets wether the content of the item is editable or not. + */ + void setItemEditable( bool editable ); + + /** + * Sets the number of lines a editable item can hold. + * -1 = unlimited. + */ + void setItemMaxlines( const QString &maxlines ); + +private: // Methods + void initActions(); + bool parseXmlFile(const QString &xmlID); + +public: // Attributes + KPopupMenu* m_popupmenu; + +private: + // Basic actions + KAction* renameItem; + KAction* deleteItem; + // Actions to create new items + KAction* newBookInfo; + KAction* newChapter; + KAction* newKeywordSet; + KAction* newKeyword; + KAction* newAbstract; + KAction* newAuthorGroup; + KAction* newAuthor; + KAction* newDate; + KAction* newReleaseInfo; + KAction* newTitle; + KAction* newParagraph; + KAction* newSection_1; + KAction* newSection_2; + KAction* newSection_3; + KAction* newSection_4; + KAction* newSection_5; + + // mixed stuff + QString m_XmlFilePath; + ListViewInterface* m_item; + QObject* m_DocTreeView; + +}; + +#endif diff --git a/ksayit/src/docbookclasses.cpp b/ksayit/src/docbookclasses.cpp new file mode 100644 index 0000000..7e5c677 --- /dev/null +++ b/ksayit/src/docbookclasses.cpp @@ -0,0 +1,1056 @@ +// +// C++ Implementation: docbookclasses +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +// Qt includes +#include <qwidget.h> +#include <qtextstream.h> +#include <qpixmap.h> +#include <qregexp.h> +#include <qstringlist.h> + +//KDE includes +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kmessagebox.h> + +// App specific includes +#include "parasaxparser.h" +#include "docbookclasses.h" + + +////////////////////////////////////// +// Interface +////////////////////////////////////// +ListViewInterface::ListViewInterface(ListViewInterface *parent, QString label) + : KListViewItem( parent, label ) +{ +} + +ListViewInterface::ListViewInterface(ListViewInterface *parent, ListViewInterface *after, QString label) : KListViewItem( parent, after, label ) +{ +} + +ListViewInterface::ListViewInterface(KListView *lv, QString label) + : KListViewItem( lv, label ) +{ +} + + +////////////////////////////////////// +// Classes for Roberts elements +////////////////////////////////////// +/** + * RobDocument + */ +RobDocument::RobDocument(KListView *lv, QString label) + : ListViewInterface( lv, label ) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("contents", KIcon::Small); + this->setPixmap(0, pixmap); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("RobDocument") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)0 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append("<H1><center>" + i18n("unnamed") + "</center></H1>"); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(i18n("unnamed") + "\n"); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +RobDocument::~RobDocument() +{ +} + +bool RobDocument::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + case KSayItGlobal::RTFHEADER: + *it = "<H1><center>" + data.toString() + "</center></H1>"; + break; + case KSayItGlobal::SPEAKERHEADER: + *it = data.toString() + "\n"; + break; + default: + return false; + } + return true; +} + +QVariant RobDocument::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + + +////////////////////////////////////// +// Classes for Docbook elements +////////////////////////////////////// +/** + * Overview + */ +Overview::Overview(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("filenew", KIcon::Small); + this->setPixmap(0, pixmap); + this->setText(3, "0"); // upmost element + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("BookInfo") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)0 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append("<H1>" + i18n("Overview") + "</H1>"); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(i18n("Overview") + "\n"); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +Overview::~Overview() +{ +} + +bool Overview::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + default: + return false; + } + return true; +} + +QVariant Overview::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + +/** + * Date + */ +Date::Date(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("filenew", KIcon::Small); + this->setPixmap(0, pixmap); + this->setText(3, "00000001"); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("Date") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)1 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append("<B>" + i18n("Date") +": </B>"); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(i18n("Date") + ": "); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +Date::~Date() +{ +} + +bool Date::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + case KSayItGlobal::MAXLINES: + *it = data; + break; + case KSayItGlobal::RTFDATA: + *it = data.toString() + "<br>"; + break; + case KSayItGlobal::SPEAKERDATA: + *it = data; + break; + case KSayItGlobal::RAWDATA: + *it = data; + break; + default: + return false; + } + return true; +} + +QVariant Date::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + +/** + * ReleaseInfo + */ +ReleaseInfo::ReleaseInfo(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("filenew", KIcon::Small); + this->setPixmap(0, pixmap); + this->setText(3, "00000002"); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("ReleaseInfo") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)1 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append("<B>" + i18n("Release") + ": </B>"); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(i18n("Release") + ": "); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +ReleaseInfo::~ReleaseInfo() +{ +} + +bool ReleaseInfo::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + case KSayItGlobal::MAXLINES: + *it = data; + break; + case KSayItGlobal::RTFDATA: + *it = data.toString() + "<br>"; + break; + case KSayItGlobal::SPEAKERDATA: + *it = data; + break; + case KSayItGlobal::RAWDATA: + *it = data; + break; + default: + return false; + } + return true; +} + +QVariant ReleaseInfo::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + +/** + * Authorgroup + */ +AuthorGroup::AuthorGroup(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("kdmconfig", KIcon::Small); + this->setPixmap(0, pixmap); + this->setText(3, "00000003"); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("AuthorGroup") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)0 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append("<H2>" + i18n("Author(s)")+ "</H2>"); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(i18n("Author(s)") + "\n"); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +AuthorGroup::~AuthorGroup() +{ +} + +bool AuthorGroup::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + default: + return false; + } + return true; +} + +QVariant AuthorGroup::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + + +/** + * Author + */ +Author::Author(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("personal", KIcon::Small); + this->setPixmap(0, pixmap); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("Author") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)1 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append("<B>" + i18n("Author") + ": </B>"); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(i18n("Author") + ": "); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +Author::~Author() +{ +} + +// void Author::setData(const QString &data, QDomDocument &) +// { +// // canonify string +// QString m_data = data; +// m_data.replace( QRegExp("\n"), "" ); // remove Newlines +// m_data.replace( QRegExp(" {2,}"), " " ); // remove multiple spaces +// m_data.replace( QRegExp("[\t|\r]{1,}"), ""); // remove Tabs +// // split string "firstname surname" +// QString firstname = m_data.section(' ', 0, 0); +// QString surname = m_data.section(' ', 1, 1); +// // update node elements +// m_node1.setNodeValue(firstname); +// m_node2.setNodeValue(surname); +// // update Listview +// this->setText(1, firstname + " " + surname); +// } + +bool Author::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + case KSayItGlobal::MAXLINES: + *it = data; + break; + case KSayItGlobal::RTFDATA: + *it = data.toString() + "<br>"; + break; + case KSayItGlobal::SPEAKERDATA: + *it = data; + this->setText( 1, data.toString() ); + break; + case KSayItGlobal::RAWDATA: + *it = data; + break; + default: + return false; + } + return true; +} + +QVariant Author::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + +/** + * KeywordSet + */ +KeywordSet::KeywordSet(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("txt", KIcon::Small); + this->setPixmap(0, pixmap); + this->setText(3, "00000004"); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("KeywordSet") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)0 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append("<H2>" + i18n("Keywords") + "</H2>"); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(i18n("Keywords") + "\n"); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +KeywordSet::~KeywordSet() +{ +} + +bool KeywordSet::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + default: + return false; + } + return true; +} + +QVariant KeywordSet::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + +/** + * Keyword + */ +Keyword::Keyword(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("Keyword") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (bool)1 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append(QString::null); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(QString::null); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +Keyword::~Keyword() +{ +} + +bool Keyword::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + case KSayItGlobal::MAXLINES: + *it = data; + break; + case KSayItGlobal::RAWDATA: + *it = data; + this->setText( 0, data.toString() ); + break; + case KSayItGlobal::RTFDATA: + *it = data.toString() + "<br>"; + break; + case KSayItGlobal::SPEAKERDATA: + *it = data; + break; + default: + return false; + } + return true; +} + +QVariant Keyword::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + + + +/** + * Abstract + */ +Abstract::Abstract(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("filenew", KIcon::Small); + this->setPixmap(0, pixmap); + this->setText(3, "00000005"); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("Abstract") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)0 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append("<H2>" + i18n("Abstract") + "</H2>"); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(i18n("Abstract") + "\n"); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +Abstract::~Abstract() +{ +} + +bool Abstract::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + default: + return false; + } + return true; +} + +QVariant Abstract::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + + +/** + * Para + */ +Para::Para(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("leftjust", KIcon::Small); + this->setPixmap(0, pixmap); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("Para") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)-1 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append(QString::null); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(i18n("Paragraph") + "\n"); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +Para::~Para() +{ +} + +bool Para::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + QString sData = QString::null; + ParaSaxParser *p = ParaSaxParser::Instance(); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + case KSayItGlobal::MAXLINES: + *it = data; + break; + case KSayItGlobal::RTFDATA: + p->setData( "<para>" + data.toString() + "</para>" ); + p->getRTFText( sData ); + *it = "<p>" + sData + "</p>"; + break; + case KSayItGlobal::SPEAKERDATA: + p->setData( "<para>" + data.toString() + "</para>" ); + p->getText( sData ); + *it = sData; + break; + case KSayItGlobal::RAWDATA: + sData = data.toString(); + *it = sData; + break; + default: + return false; + } + return true; +} + +QVariant Para::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + + +/** + * Chapter + */ +Chapter::Chapter(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("leftjust", KIcon::Small); + this->setPixmap(0, pixmap); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("Chapter") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)0 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append(QString::null); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(QString::null); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +Chapter::~Chapter() +{ +} + +bool Chapter::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + case KSayItGlobal::RTFHEADER: + *it = "<H1>" + data.toString() + "</H1>"; + break; + case KSayItGlobal::SPEAKERHEADER: + *it = data.toString() + "\n"; + break; + default: + return false; + } + return true; +} + +QVariant Chapter::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + + +/** + * Sect1 + */ +Sect1::Sect1(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("leftjust", KIcon::Small); + this->setPixmap(0, pixmap); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("Sect1") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)0 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append(QString::null); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(QString::null); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +Sect1::~Sect1() +{ +} + +bool Sect1::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + case KSayItGlobal::RTFHEADER: + *it = "<H2>" + data.toString() + "</H2>"; + break; + case KSayItGlobal::SPEAKERHEADER: + *it = data.toString() + "\n"; + break; + default: + return false; + } + return true; +} + +QVariant Sect1::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + +/** + * Sect2 + */ +Sect2::Sect2(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("leftjust", KIcon::Small); + this->setPixmap(0, pixmap); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("Sect2") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)0 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append(QString::null); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(QString::null); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +Sect2::~Sect2() +{ +} + +bool Sect2::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + case KSayItGlobal::RTFHEADER: + *it = "<H3>" + data.toString() + "</H3>"; + break; + case KSayItGlobal::SPEAKERHEADER: + *it = data.toString() + "\n"; + break; + default: + return false; + } + return true; +} + +QVariant Sect2::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + +/** + * Sect3 + */ +Sect3::Sect3(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("leftjust", KIcon::Small); + this->setPixmap(0, pixmap); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("Sect3") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)0 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append(QString::null); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(QString::null); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +Sect3::~Sect3() +{ +} + +bool Sect3::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + case KSayItGlobal::RTFHEADER: + *it = "<B>" + data.toString() + "</B><br>"; + break; + case KSayItGlobal::SPEAKERHEADER: + *it = data.toString() + "\n"; + break; + default: + return false; + } + return true; +} + +QVariant Sect3::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + +/** + * Sect4 + */ +Sect4::Sect4(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("leftjust", KIcon::Small); + this->setPixmap(0, pixmap); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("Sect4") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)0 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append(QString::null); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(QString::null); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +Sect4::~Sect4() +{ +} + +bool Sect4::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + case KSayItGlobal::RTFHEADER: + *it = "<B>" + data.toString() + "</B><br>"; + break; + case KSayItGlobal::SPEAKERHEADER: + *it = data.toString() + "\n"; + break; + default: + return false; + } + return true; +} + +QVariant Sect4::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + +/** + * Sect5 + */ +Sect5::Sect5(ListViewInterface *parent, ListViewInterface *after, QString label) + : ListViewInterface(parent, after, label) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon("leftjust", KIcon::Small); + this->setPixmap(0, pixmap); + + // new Concept (begin) + m_valueList.clear(); + m_valueList.append( QString("Sect5") ); // XmlContextName + m_valueList.append( (bool)false ); // isEditable + m_valueList.append( (int)0 ); // MaxLines + m_valueList.append(QString::null); // Summary + m_valueList.append(QString::null); // RawData + m_valueList.append(QString::null); // RTFHeader + m_valueList.append(QString::null); // RTFData + m_valueList.append(QString::null); // SpeakerHeader + m_valueList.append(QString::null); // SpeakerData + // new Concept (end) +} + +Sect5::~Sect5() +{ +} + +bool Sect5::setValue( unsigned int index, QVariant data ) +{ + if ( index<1 || index > m_valueList.count() ) + return false; + + QValueList<QVariant>::Iterator it = m_valueList.at(index); + switch (index){ + case KSayItGlobal::ISEDITABLE: + *it = data; + break; + case KSayItGlobal::RTFHEADER: + *it = "<B>" + data.toString() + "</B><br>"; + break; + case KSayItGlobal::SPEAKERHEADER: + *it = data.toString() + "\n"; + break; + default: + return false; + } + return true; +} + +QVariant Sect5::getValue( unsigned int index ) const +{ + if ( index > m_valueList.count() ) + return QVariant(); // a invalid QVariant + + QVariant data; + data = m_valueList[index]; + + return data; +} + diff --git a/ksayit/src/docbookclasses.h b/ksayit/src/docbookclasses.h new file mode 100644 index 0000000..a7f84af --- /dev/null +++ b/ksayit/src/docbookclasses.h @@ -0,0 +1,344 @@ +// +// C++ Interface: docbookclasses.h +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef DOCBOOKCLASSES_H +#define DOCBOOKCLASSES_H + +// Qt includes +#include <qstring.h> + +#include <qvariant.h> +#include <qvaluelist.h> + +// KDE includes +#include <klistview.h> + +// App specific includes +#include "Types.h" + +// forward declarations +class QStringList; + +// +// Classes for Roberts elements +// +/** + Represents the root item of the document, therefore it expects + a \p QListView object as parent.\n + Structural item only (no references to a DOM node). + @author Robert Vogl + */ +class RobDocument : public ListViewInterface +{ +public: + /** + * Constructor + * \param lv The ListView parent. + * \param label The label is shown in column 0 of the TreeView and is also + * used as bookmark title. + */ + RobDocument(KListView *lv=0, QString label=QString::null); + ~RobDocument(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +// +// Classes for Docbook elements +// +/** + Represents the DocBook \p Overview element of the document.\n + Structural item only (no references to a DOM node). + @author Robert Vogl + */ +class Overview : public ListViewInterface +{ +public: + Overview(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~Overview(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p Date element of the document.\n + @author Robert Vogl + */ +class Date : public ListViewInterface +{ +public: + Date(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~Date(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + // Pointer to the associated Data + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p ReleasInfo element of the document.\n + @author Robert Vogl + */ +class ReleaseInfo : public ListViewInterface +{ +public: + ReleaseInfo(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~ReleaseInfo(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + // Pointer to the associated Data + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p AuthorGroup element of the document.\n + Structural item only (no references to a DOM node). + @author Robert Vogl + */ +class AuthorGroup : public ListViewInterface +{ +public: + AuthorGroup(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~AuthorGroup(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p Author element and its Subelements + \p Firstname and \p Surname of the document.\n + @author Robert Vogl + */ +class Author : public ListViewInterface +{ +public: + Author(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~Author(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p KeywordSet element of the document.\n + Structural item only (no references to a DOM node). + @author Robert Vogl + */ +class KeywordSet : public ListViewInterface +{ +public: + KeywordSet(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~KeywordSet(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p Keyword element of the document.\n + @author Robert Vogl + */ +class Keyword : public ListViewInterface +{ +public: + Keyword(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~Keyword(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p Abstract element of the document.\n + Structural item only (no references to a DOM node). + @author Robert Vogl + */ +class Abstract : public ListViewInterface +{ +public: + Abstract(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~Abstract(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +/** + Represents a DocBook Paragraph item of the document.\n + @author Robert Vogl + */ +class Para : public ListViewInterface +{ +public: + Para(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~Para(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p Chapter element of the document.\n + Structural item only (no references to a DOM node). + @author Robert Vogl + */ +class Chapter : public ListViewInterface +{ +public: + Chapter(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~Chapter(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p Sec1 element of the document.\n + Structural item only (no references to a DOM node). + @author Robert Vogl + */ +class Sect1 : public ListViewInterface +{ +public: + Sect1(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~Sect1(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p Sec2 element of the document.\n + Structural item only (no references to a DOM node). + @author Robert Vogl + */ +class Sect2 : public ListViewInterface +{ +public: + Sect2(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~Sect2(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p Sec3 element of the document.\n + Structural item only (no references to a DOM node). + @author Robert Vogl + */ +class Sect3 : public ListViewInterface +{ +public: + Sect3(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~Sect3(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p Sec4 element of the document.\n + Structural item only (no references to a DOM node). + @author Robert Vogl + */ +class Sect4 : public ListViewInterface +{ +public: + Sect4(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~Sect4(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + + +/** + Represents the DocBook \p Sec5 element of the document.\n + Structural item only (no references to a DOM node). + @author Robert Vogl + */ +class Sect5 : public ListViewInterface +{ +public: + Sect5(ListViewInterface *parent=0, ListViewInterface *after=0, QString label=QString::null); + ~Sect5(); + + bool setValue( unsigned int index, QVariant data ); + QVariant getValue( unsigned int index ) const; + +private: + QValueList<QVariant> m_valueList; +}; + +#endif diff --git a/ksayit/src/docbookgenerator.cpp b/ksayit/src/docbookgenerator.cpp new file mode 100644 index 0000000..1d6db9c --- /dev/null +++ b/ksayit/src/docbookgenerator.cpp @@ -0,0 +1,483 @@ +// +// C++ Implementation: docbookgenerator +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +// Qt includes +#include <qstring.h> +#include <qvariant.h> + +//KDE includes +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> + +// App specific includes +#include "docbookgenerator.h" + + +DocbookGenerator::DocbookGenerator() +{ +} + + +DocbookGenerator::~DocbookGenerator() +{ +} + + +void DocbookGenerator::writeBook(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeBook()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "RobDocument" ) + return; + + // add node to document + doc << "<Book>" << endl; + + // process childs + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + QString itemType; + while( i ){ + itemType = (i->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( itemType == "BookInfo" ){ + writeBookInfo( doc, i ); + } else if ( itemType == "Chapter" ) { + writeChapter( doc, i ); + } + // next child + i = static_cast<ListViewInterface*>(i->nextSibling()); + } + doc << "</Book>" << endl; +} + + +void DocbookGenerator::writeBookInfo(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeBookInfo()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "BookInfo" ) + return; + + // add node to document + doc << "<BookInfo>" << endl; + writeTitleOfBook( doc, item ); + + // process childs + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + QString itemType; + while( i ){ + itemType = (i->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( itemType == "KeywordSet" ){ + writeKeywordSet( doc, i ); + } else if ( itemType == "Abstract" ) { + writeAbstract( doc, i ); + } else if ( itemType == "AuthorGroup" ) { + writeAuthorGroup( doc, i ); + } else if ( itemType == "Date" ) { + writeDate( doc, i ); + } else if ( itemType == "ReleaseInfo" ) { + writeReleaseInfo( doc, i ); + } + // next child + i = static_cast<ListViewInterface*>(i->nextSibling()); + } + + doc << "</BookInfo>" << endl; +} + + +void DocbookGenerator::writeTitleOfBook(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeTitle()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "BookInfo" ) + return; + + // Documents title is stored in root element (parent of BookInfo) + ListViewInterface *parent = static_cast<ListViewInterface*>(item->parent()); + if ( parent ){ + QString title = parent->text(0); + + // add node to document + doc << "<Title>" << title << "</Title>" << endl; + } +} + + +void DocbookGenerator::writeAuthorGroup(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeAuthorGroup()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "AuthorGroup" ) + return; + + // add node to document + doc << "<AuthorGroup>" << endl; + + // process childs + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + QString itemType; + while( i ){ + itemType = (i->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( itemType == "Author" ){ + writeAuthor( doc, i ); + } + // next child + i = static_cast<ListViewInterface*>(i->nextSibling()); + } + + doc << "</AuthorGroup>" << endl; +} + + +void DocbookGenerator::writeAuthor(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeAuthor()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "Author" ) + return; + + QString author = QString::null; + author = ( item->getValue(KSayItGlobal::RAWDATA) ).toString(); + + // add node to document + doc << "<Author>" << endl; + + // process childs + doc << "<Firstname>" << author.section(' ', 0, 0) << "</Firstname>" << endl; + doc << "<Surname>" << author.section(' ', 1, 1) << "</Surname>" << endl; + + doc << "</Author>" << endl; +} + + +void DocbookGenerator::writeDate(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeDate()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "Date" ) + return; + + QString date = item->text(1); + + // add node to document + doc << "<Date>" << date << "</Date>" << endl; +} + + +void DocbookGenerator::writeReleaseInfo(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeReleaseInfo()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "ReleaseInfo" ) + return; + + QString releaseinfo = item->text(1); + + // add node to document + doc << "<ReleaseInfo>" << releaseinfo << "</ReleaseInfo>" << endl; +} + + +void DocbookGenerator::writeKeywordSet(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeKeywordSet()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "KeywordSet" ) + return; + + // add node to document + doc << "<KeywordSet>" << endl; + + // process childs + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + QString itemType; + while( i ){ + itemType = ( i->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( itemType == "Keyword" ){ + writeKeyword( doc, i ); + } + // next child + i = static_cast<ListViewInterface*>(i->nextSibling()); + } + + doc << "</KeywordSet>" << endl; +} + + +void DocbookGenerator::writeKeyword(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeKeyword()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "Keyword" ) + return; + + // QString keyword = item->text( 0 ); + QString keyword = QString::null; + keyword = (item->getValue(3)).toString(); + + // add node to document + doc << "<Keyword>" << keyword << "</Keyword>" << endl; + + // process childs + // no childs +} + + +void DocbookGenerator::writeAbstract(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeAbstract()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "Abstract" ) + return; + + // add node to document + doc << "<Abstract>" << endl; + + // process childs + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + QString itemType; + while( i ){ + itemType = (i->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( itemType == "Para" ){ + writePara( doc, i ); + } + // next child + i = static_cast<ListViewInterface*>(i->nextSibling()); + } + + doc << "</Abstract>" << endl; +} + + +void DocbookGenerator::writeChapter( QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeChapter()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "Chapter" ) + return; + + QString title = item->text(0); + + // add node to document + doc << "<Chapter>" << endl; + doc << "<Title>" << title << "</Title>" << endl; + + // process childs + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + QString itemType; + while( i ){ + itemType = (i->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( itemType == "Para" ){ + writePara( doc, i ); + } else if ( itemType == "Sect1" ) { + writeSect1( doc, i ); + } + // next child + i = static_cast<ListViewInterface*>(i->nextSibling()); + } + + doc << "</Chapter>" << endl; +} + + +void DocbookGenerator::writeSect1(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeSect1()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "Sect1" ) + return; + + QString title = item->text(0); + + // add node to document + doc << "<Sect1>" << endl; + doc << "<Title>" << title << "</Title>" << endl; + + // process childs + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + QString itemType; + while( i ){ + itemType = (i->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( itemType == "Para" ){ + writePara( doc, i ); + } else if ( itemType == "Sect2" ) { + writeSect2( doc, i ); + } + // next child + i = static_cast<ListViewInterface*>(i->nextSibling()); + } + + doc << "</Sect1>" << endl; +} + + +void DocbookGenerator::writeSect2(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeSect1()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "Sect2" ) + return; + + QString title = item->text(0); + + // add node to document + doc << "<Sect2>" << endl; + doc << "<Title>" << title << "</Title>" << endl; + + // process childs + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + QString itemType; + while( i ){ + itemType = ( i->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( itemType == "Para" ){ + writePara( doc, i ); + } else if ( itemType == "Sect3" ) { + writeSect3( doc, i ); + } + // next child + i = static_cast<ListViewInterface*>(i->nextSibling()); + } + + doc << "</Sect2>" << endl; +} + + +void DocbookGenerator::writeSect3(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeSect3()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "Sect3" ) + return; + + QString title = item->text(0); + + // add node to document + doc << "<Sect3>" << endl; + doc << "<Title>" << title << "</Title>" << endl; + + // process childs + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + QString itemType; + while( i ){ + itemType = (i->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( itemType == "Para" ){ + writePara( doc, i ); + } else if ( itemType == "Sect4" ) { + writeSect4( doc, i ); + } + // next child + i = static_cast<ListViewInterface*>(i->nextSibling()); + } + + doc << "</Sect3>" << endl; +} + + +void DocbookGenerator::writeSect4(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeSect4()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "Sect4" ) + return; + + QString title = item->text(0); + + // add node to document + doc << "<Sect4>" << endl; + doc << "<Title>" << title << "</Title>" << endl; + + // process childs + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + QString itemType; + while( i ){ + itemType = (i->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( itemType == "Para" ){ + writePara( doc, i ); + } else if ( itemType == "Sect5" ) { + writeSect5( doc, i ); + } + // next child + i = static_cast<ListViewInterface*>(i->nextSibling()); + } + + doc << "</Sect4>" << endl; +} + + +void DocbookGenerator::writeSect5(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writeSect5()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "Sect5" ) + return; + + QString title = item->text(0); + + // add node to document + doc << "<Sect5>" << endl; + doc << "<Title>" << title << "</Title>" << endl; + + // process childs + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + QString itemType; + while( i ){ + itemType = (i->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( itemType == "Para" ){ + writePara( doc, i ); + } + // next child + i = static_cast<ListViewInterface*>(i->nextSibling()); + } + + doc << "</Sect5>" << endl; +} + + +void DocbookGenerator::writePara(QTextStream &doc, ListViewInterface *item) +{ + kdDebug(100200) << "DocTreeViewImpl::writePara()" << endl; + // read item's content + QString whoAmI = (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString(); + if ( whoAmI != "Para" ) + return; + + QString data = ( item->getValue(KSayItGlobal::RAWDATA) ).toString(); + + // add node to document + doc << "<Para>" << endl; + doc << data << endl; + doc << "</Para>" << endl; + + // process childs + // childs are embedded in data. +} + + + + diff --git a/ksayit/src/docbookgenerator.h b/ksayit/src/docbookgenerator.h new file mode 100644 index 0000000..80f526b --- /dev/null +++ b/ksayit/src/docbookgenerator.h @@ -0,0 +1,71 @@ +// +// C++ Interface: docbookgenerator +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef DOCBOOKGENERATOR_H +#define DOCBOOKGENERATOR_H + +// Qt includes +#include <qtextstream.h> + +// KDE includes + +// App specific includes +#include "Types.h" + +class DocbookGenerator +{ +public: + // Constructor + DocbookGenerator(); + + // Destructor + ~DocbookGenerator(); + + /** + * Walks throug the entire treeview starting with given item and returns + * returns a DocBook representation of its content. + * \returns doc The content of the TreeView in DocBook format + * \param item A pointer to the root item of the tree. Must be of type + * \p RobDocument. + */ + void writeBook(QTextStream &doc, ListViewInterface *item); + + +private: + void writeBookInfo(QTextStream &doc, ListViewInterface *item); + void writeTitleOfBook(QTextStream &doc, ListViewInterface *item); + void writeChapter(QTextStream &doc, ListViewInterface *item); + void writeKeywordSet(QTextStream &doc, ListViewInterface *item); + void writeKeyword(QTextStream &doc, ListViewInterface *item); + void writeAbstract(QTextStream &doc, ListViewInterface *item); + void writePara(QTextStream &doc, ListViewInterface *item); + void writeAuthorGroup(QTextStream &doc, ListViewInterface *item); + void writeAuthor(QTextStream &doc, ListViewInterface *item); + void writeDate(QTextStream &doc, ListViewInterface *item); + void writeReleaseInfo(QTextStream &doc, ListViewInterface *item); + void writeSect1(QTextStream &doc, ListViewInterface *item); + void writeSect2(QTextStream &doc, ListViewInterface *item); + void writeSect3(QTextStream &doc, ListViewInterface *item); + void writeSect4(QTextStream &doc, ListViewInterface *item); + void writeSect5(QTextStream &doc, ListViewInterface *item); + + + +}; + + + + + + + +#endif + diff --git a/ksayit/src/docbookparser.cpp b/ksayit/src/docbookparser.cpp new file mode 100644 index 0000000..03b9f73 --- /dev/null +++ b/ksayit/src/docbookparser.cpp @@ -0,0 +1,493 @@ +// +// C++ Implementation: docbookparser +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +// Qt includes +#include <qregexp.h> +#include <qstring.h> +#include <qtextstream.h> + +//KDE includes +#include <kdebug.h> +#include <klocale.h> + +// App specific includes +#include "docbookparser.h" +#include "docbookclasses.h" + + +DocbookParser::DocbookParser(ContextMenuHandler *cmHandler) +{ + m_contextmenuhandler = cmHandler; + m_idCounter = KSayItGlobal::item_initial_id; +} + + +DocbookParser::~DocbookParser() +{ +} + + +QString DocbookParser::node2raw(QDomNode node) const +{ + QString ret; + + // get content of element + QTextStream in(ret, IO_WriteOnly); + in.setEncoding(QTextStream::UnicodeUTF8); + in << node; + + return ret; +} + + +/****************************************** + * XML-Parser functions + ******************************************/ +// +// DocBook parser +// +void DocbookParser::parseBook(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parseBook()" << endl; + item->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + // register Popup menu + m_contextmenuhandler->registerPopupMenu( item ); + + // TODO: Attributes Id, Lang + + // Elements (parse BookInfo before Chapter) + QDomNode node = element.firstChild(); + while( !node.isNull() ){ + if( node.isElement() && node.nodeName().lower()=="bookinfo" ){ + parseBookInfo( node.toElement(), item ); + break; + } + node = node.nextSibling(); + } + node = element.firstChild(); + while( !node.isNull() ){ + if ( node.isElement() && node.nodeName().lower()=="chapter" ){ + parseChapter( node.toElement(), item ); + } + node = node.nextSibling(); + } + kdDebug(100200) << "--- leaving parseBook()" << endl; +} + + +void DocbookParser::parseBookInfo(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parseBookInfo()" << endl; + + Overview *overview = new Overview(item, NULL, i18n("Overview")); + overview->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + // register Popup menu + m_contextmenuhandler->registerPopupMenu( overview ); + + QDomText data; + QDomNode node = element.firstChild(); + // fixed order + while( !node.isNull() ){ + if( node.isElement() && node.nodeName().lower()=="title" ){ + data = node.firstChild().toText(); + if( !data.isNull() ){ + item->setText( 0, data.nodeValue() ); // assign title to RootItem + item->setValue(KSayItGlobal::RTFHEADER, data.nodeValue() ); + item->setValue(KSayItGlobal::SPEAKERHEADER, data.nodeValue() ); + + break; + } + } + node = node.nextSibling(); + } + node = element.firstChild(); + while( !node.isNull() ){ + if ( node.isElement() && node.nodeName().lower()=="authorgroup" ){ + parseAuthorGroup( node.toElement(), overview ); + } + node = node.nextSibling(); + } + node = element.firstChild(); + while( !node.isNull() ){ + if ( node.isElement() && node.nodeName().lower()=="date" ){ + data = node.firstChild().toText(); + if( !data.isNull() ){ + Date *date = new Date(overview, NULL, i18n("Date")); + date->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + date->setText( 1, data.nodeValue() ); + date->setValue(KSayItGlobal::RTFDATA, data.nodeValue()); + date->setValue(KSayItGlobal::SPEAKERDATA, data.nodeValue()); + date->setValue(KSayItGlobal::RAWDATA, node2raw(data)); + + // register Popup menu + m_contextmenuhandler->registerPopupMenu( date ); + } + } + node = node.nextSibling(); + } + node = element.firstChild(); + while( !node.isNull() ){ + if ( node.isElement() && node.nodeName().lower()=="releaseinfo" ){ + data = node.firstChild().toText(); + if( !data.isNull() ){ + ReleaseInfo *relinfo = new ReleaseInfo(overview, NULL, i18n("Release")); + relinfo->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + relinfo->setText( 1, data.nodeValue() ); + relinfo->setValue(KSayItGlobal::RTFDATA, data.nodeValue()); + relinfo->setValue(KSayItGlobal::SPEAKERDATA, data.nodeValue()); + relinfo->setValue(KSayItGlobal::RAWDATA, node2raw(data)); + + // register Popup menu + m_contextmenuhandler->registerPopupMenu( relinfo ); + } + } + node = node.nextSibling(); + } + node = element.firstChild(); + while( !node.isNull() ){ + if ( node.isElement() && node.nodeName().lower()=="keywordset" ){ + parseKeywordSet( node.toElement(), overview ); + } + node = node.nextSibling(); + } + node = element.firstChild(); + while( !node.isNull() ){ + if ( node.isElement() && node.nodeName().lower()=="abstract" ){ + parseAbstract( node.toElement(), overview ); + } + node = node.nextSibling(); + } + kdDebug(100200) << "--- leaving parseBookInfo()" << endl; +} + + +void DocbookParser::parseAuthorGroup(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parseAuthorGroup()" << endl; + + // item = overview + AuthorGroup *authorgroup = new AuthorGroup(item, NULL, i18n("Author(s)")); + authorgroup->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + // register Popup menu + m_contextmenuhandler->registerPopupMenu( authorgroup ); + + QDomNode node = element.firstChild(); + while( !node.isNull() ){ + if( node.isElement() && node.nodeName().lower()=="author" ){ + parseAuthor( node.toElement(), authorgroup ); + } + node = node.nextSibling(); + } + kdDebug(100200) << "--- leaving parseAuthorGroup()" << endl; +} + + +void DocbookParser::parseAuthor(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parseAuthor()" << endl; + + // item = authorgroup + QDomText data; + QDomText firstname = QDomText(); + QDomText surname = QDomText(); + QString s_firstname = QString::null; + QString s_surname = QString::null; + + Author *author = new Author(item); + author->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + + QDomNode node = element.firstChild(); + while( !node.isNull() ){ + if( node.isElement() && node.nodeName().lower()=="firstname" ){ + data = node.firstChild().toText(); + if( !data.isNull() ){ + s_firstname = data.nodeValue(); + firstname = data; + } + } else if ( node.isElement() && node.nodeName().lower()=="surname" ){ + data = node.firstChild().toText(); + if( !data.isNull() ){ + s_surname = data.nodeValue(); + surname = data; + } + } + node = node.nextSibling(); + } + // register Popup menu + m_contextmenuhandler->registerPopupMenu( author ); + + author->setText(0, i18n("Author") ); + author->setText(1, s_firstname + " " + s_surname); + author->setValue(KSayItGlobal::RTFDATA, s_firstname + " " + s_surname); + author->setValue(KSayItGlobal::SPEAKERDATA, s_firstname + " " + s_surname); + author->setValue(KSayItGlobal::RAWDATA, s_firstname + " " + s_surname); + + kdDebug(100200) << "--- leaving parseAuthor()" << endl; +} + + +void DocbookParser::parseKeywordSet(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parseKeywordSet()" << endl; + + // item = overview + KeywordSet *keywordset = new KeywordSet(item, NULL, i18n("Keywords")); + keywordset->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + // register Popup menu + m_contextmenuhandler->registerPopupMenu( keywordset ); + + QDomText data; + QDomNode node = element.firstChild(); + while( !node.isNull() ){ + if( node.isElement() && node.nodeName().lower()=="keyword" ){ + data = node.firstChild().toText(); + if( !data.isNull() ){ + Keyword *keyword = new Keyword(keywordset); + keyword->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + keyword->setText(0, data.nodeValue() ); + keyword->setValue(KSayItGlobal::RTFDATA, data.nodeValue() ); + keyword->setValue(KSayItGlobal::SPEAKERDATA, data.nodeValue() ); + keyword->setValue(KSayItGlobal::RAWDATA, node2raw(data) ); + + // register Popup menu + m_contextmenuhandler->registerPopupMenu( keyword ); + } + } + node = node.nextSibling(); + } + kdDebug(100200) << "--- leaving parseKeywordSet()" << endl; +} + + +void DocbookParser::parseAbstract(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parseAbstract()" << endl; + + // item = overview + QDomText data; + Abstract *abstract = new Abstract(item, NULL, i18n("Abstract")); + abstract->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + // register Popup menu + m_contextmenuhandler->registerPopupMenu( abstract ); + + QDomNode node = element.firstChild(); + while( !node.isNull() ){ + if( node.isElement() && node.nodeName().lower()=="para" ){ + parsePara( node.toElement(), abstract ); + } + node = node.nextSibling(); + } + kdDebug(100200) << "--- leaving parseAbstract()" << endl; +} + + +void DocbookParser::parseChapter(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parseChapter()" << endl; + + QDomText data; + Chapter *chapter = new Chapter(item, NULL, i18n("Chapter")); + chapter->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + // register Popup menu + m_contextmenuhandler->registerPopupMenu( chapter ); + + QDomNode node = element.firstChild(); + while( !node.isNull() ){ + if( node.isElement() && node.nodeName().lower()=="title" ){ + data = node.firstChild().toText(); + if( !data.isNull() ){ + chapter->setText( 0, data.nodeValue() ); + chapter->setValue(KSayItGlobal::RTFHEADER, data.nodeValue()); + chapter->setValue(KSayItGlobal::SPEAKERHEADER, data.nodeValue()); + } + } else if ( node.isElement() && node.nodeName().lower()=="para" ){ + parsePara( node.toElement(), chapter ); + } else if ( node.isElement() && node.nodeName().lower()=="sect1" ){ + parseSect1( node.toElement(), chapter ); + } + node = node.nextSibling(); + } + kdDebug(100200) << "--- leaving parseChapter()" << endl; +} + + +void DocbookParser::parseSect1(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parseSect1()" << endl; + + QDomText data; + Sect1 *sect1 = new Sect1(item, NULL, i18n("Section Level 1")); + sect1->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + // register Popup menu + m_contextmenuhandler->registerPopupMenu( sect1 ); + + QDomNode node = element.firstChild(); + while( !node.isNull() ){ + if( node.isElement() && node.nodeName().lower()=="title" ){ + data = node.firstChild().toText(); + if( !data.isNull() ){ + sect1->setText( 0, data.nodeValue() ); + sect1->setValue(KSayItGlobal::RTFHEADER, data.nodeValue()); + sect1->setValue(KSayItGlobal::SPEAKERHEADER, data.nodeValue()); + } + } else if ( node.isElement() && node.nodeName().lower()=="para" ){ + parsePara( node.toElement(), sect1 ); + } else if ( node.isElement() && node.nodeName().lower()=="sect2" ){ + parseSect2( node.toElement(), sect1 ); + } + node = node.nextSibling(); + } + kdDebug(100200) << "--- leaving parseSect1()" << endl; +} + + +void DocbookParser::parseSect2(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parseSect2()" << endl; + + QDomText data; + Sect2 *sect2 = new Sect2(item, NULL, i18n("Section Level 2")); + sect2->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + // register Popup menu + m_contextmenuhandler->registerPopupMenu( sect2 ); + + QDomNode node = element.firstChild(); + while( !node.isNull() ){ + if( node.isElement() && node.nodeName().lower()=="title" ){ + data = node.firstChild().toText(); + if( !data.isNull() ){ + sect2->setText( 0, data.nodeValue() ); + sect2->setValue(KSayItGlobal::RTFHEADER, data.nodeValue()); + sect2->setValue(KSayItGlobal::SPEAKERHEADER, data.nodeValue()); + } + } else if ( node.isElement() && node.nodeName().lower()=="para" ){ + parsePara( node.toElement(), sect2 ); + } else if ( node.isElement() && node.nodeName().lower()=="sect3" ){ + parseSect3( node.toElement(), sect2 ); + } + node = node.nextSibling(); + } + kdDebug(100200) << "--- leaving parseSect2()" << endl; +} + + +void DocbookParser::parseSect3(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parseSect3()" << endl; + + QDomText data; + Sect3 *sect3 = new Sect3(item, NULL, i18n("Section Level 3")); + sect3->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + // register Popup menu + m_contextmenuhandler->registerPopupMenu( sect3 ); + + QDomNode node = element.firstChild(); + while( !node.isNull() ){ + if( node.isElement() && node.nodeName().lower()=="title" ){ + data = node.firstChild().toText(); + if( !data.isNull() ){ + sect3->setText( 0, data.nodeValue() ); + sect3->setValue(KSayItGlobal::RTFHEADER, data.nodeValue()); + sect3->setValue(KSayItGlobal::SPEAKERHEADER, data.nodeValue()); + } + } else if ( node.isElement() && node.nodeName().lower()=="para" ){ + parsePara( node.toElement(), sect3 ); + } else if ( node.isElement() && node.nodeName().lower()=="sect4" ){ + parseSect4( node.toElement(), sect3 ); + } + node = node.nextSibling(); + } + kdDebug(100200) << "--- leaving parseSect3()" << endl; +} + + +void DocbookParser::parseSect4(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parseSect4()" << endl; + + QDomText data; + Sect4 *sect4 = new Sect4(item, NULL, i18n("Section Level 4")); + sect4->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + // register Popup menu + m_contextmenuhandler->registerPopupMenu( sect4 ); + + QDomNode node = element.firstChild(); + while( !node.isNull() ){ + if( node.isElement() && node.nodeName().lower()=="title" ){ + data = node.firstChild().toText(); + if( !data.isNull() ){ + sect4->setText( 0, data.nodeValue() ); + sect4->setValue(KSayItGlobal::RTFHEADER, data.nodeValue()); + sect4->setValue(KSayItGlobal::SPEAKERHEADER, data.nodeValue()); + } + } else if ( node.isElement() && node.nodeName().lower()=="para" ){ + parsePara( node.toElement(), sect4 ); + } else if ( node.isElement() && node.nodeName().lower()=="sect5" ){ + parseSect5( node.toElement(), sect4 ); + } + node = node.nextSibling(); + } + kdDebug(100200) << "--- leaving parseSect4()" << endl; +} + + +void DocbookParser::parseSect5(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parseSect5()" << endl; + + QDomText data; + Sect5 *sect5 = new Sect5(item, NULL, i18n("Section Level 4")); + sect5->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + // register Popup menu + m_contextmenuhandler->registerPopupMenu( sect5 ); + + QDomNode node = element.firstChild(); + while( !node.isNull() ){ + if( node.isElement() && node.nodeName().lower()=="title" ){ + data = node.firstChild().toText(); + if( !data.isNull() ){ + sect5->setText( 0, data.nodeValue() ); + sect5->setValue(KSayItGlobal::RTFHEADER, data.nodeValue()); + sect5->setValue(KSayItGlobal::SPEAKERHEADER, data.nodeValue()); + } + } else if ( node.isElement() && node.nodeName().lower()=="para" ){ + parsePara( node.toElement(), sect5 ); + } + node = node.nextSibling(); + } + kdDebug(100200) << "--- leaving parseSect5()" << endl; +} + + +void DocbookParser::parsePara(const QDomElement &element, ListViewInterface *item) +{ + kdDebug(100200) << "+++ entering parsePara()" << endl; + + Para *para = new Para(item, NULL, i18n("Paragraph")); + para->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + // register Popup menu + m_contextmenuhandler->registerPopupMenu( para ); + + QString raw = node2raw(element); + // remove <para> tags + raw.replace( QRegExp("</?(para|Para|PARA)/?>"),""); + raw.replace( QRegExp("^ "),"" ); + raw.replace( QRegExp("^\n"), "" ); + + para->setValue(KSayItGlobal::RAWDATA, raw); + para->setValue(KSayItGlobal::RTFDATA, raw); + para->setValue(KSayItGlobal::SPEAKERDATA, raw); + + kdDebug(100200) << "--- leaving parsePara()" << endl; +} + + diff --git a/ksayit/src/docbookparser.h b/ksayit/src/docbookparser.h new file mode 100644 index 0000000..e603e93 --- /dev/null +++ b/ksayit/src/docbookparser.h @@ -0,0 +1,64 @@ +// +// C++ Interface: docbookparser +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef DOCBOOKPARSER_H +#define DOCBOOKPARSER_H + +// Qt includes +#include <qdom.h> + +// KDE includes + +// App specific includes +#include "Types.h" +#include "contextmenuhandler.h" + + +class DocbookParser +{ +public: + // Constructor + DocbookParser(ContextMenuHandler *cmHandler=0); + + // Destructor + ~DocbookParser(); + + void parseBook(const QDomElement &element, ListViewInterface *item); + + int getIdCounter(){ return m_idCounter; }; + +private: // Methods + // a selection of DocBook elements + void parseBookInfo(const QDomElement &element, ListViewInterface *item); + void parseAuthorGroup(const QDomElement &element, ListViewInterface *item); + void parseAuthor(const QDomElement &element, ListViewInterface *item); + void parseKeywordSet(const QDomElement &element, ListViewInterface *item); + void parseAbstract(const QDomElement &element, ListViewInterface *item); + void parseChapter(const QDomElement &element, ListViewInterface *item); + void parseSect1(const QDomElement &element, ListViewInterface *item); + void parseSect2(const QDomElement &element, ListViewInterface *item); + void parseSect3(const QDomElement &element, ListViewInterface *item); + void parseSect4(const QDomElement &element, ListViewInterface *item); + void parseSect5(const QDomElement &element, ListViewInterface *item); + void parsePara(const QDomElement &element, ListViewInterface *item); + + // Helpers + QString node2raw(QDomNode node) const; + +private: // Attributes + ContextMenuHandler *m_contextmenuhandler; + int m_idCounter; + +}; + +#endif + + diff --git a/ksayit/src/doctreeviewimpl.cpp b/ksayit/src/doctreeviewimpl.cpp new file mode 100644 index 0000000..663933b --- /dev/null +++ b/ksayit/src/doctreeviewimpl.cpp @@ -0,0 +1,1141 @@ +// +// C++ Implementation: doctreeviewimpl +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include <stdlib.h> // getenv + +// Qt includes +#include <qdom.h> +#include <qfile.h> +#include <qwidget.h> +#include <qtextstream.h> +#include <qregexp.h> +#include <qdatetime.h> +#include <qcolor.h> +#include <qlistview.h> + +//KDE includes +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> +#include <kfiledialog.h> +#include <kmessagebox.h> +#include <kinputdialog.h> + +// App specific includes +#include "doctreeviewimpl.h" +#include "contextmenuhandler.h" +#include "parasaxparser.h" +#include "docbookclasses.h" +#include "docbookgenerator.h" +#include "docbookparser.h" + + +////////////////////////////////////// +// TreeView Implementation +////////////////////////////////////// +DocTreeViewImpl::DocTreeViewImpl(QWidget* parent, const char* name, WFlags fl) + : DocTreeView(parent, name, fl) +{ + m_rootItem = NULL; + m_url = KURL(); + // the hidden formated id to set a sort order + listView->setSorting(3, true); + listView->setColumnText(0, i18n("Chapter")); + listView->setColumnText(1, i18n("Info")); + listView->setColumnText(2, i18n("Page")); + listView->setColumnText(3, ""); + listView->setResizeMode( KListView::NoColumn ); + listView->setColumnWidthMode(0, KListView::Maximum ); + listView->setColumnWidthMode(1, KListView::Maximum ); + listView->setColumnWidthMode(2, KListView::Maximum ); + listView->setColumnWidthMode(3, KListView::Manual ); + listView->setColumnWidth(3, 0); + listView->setAlternateBackground( QColor(230, 230, 240) ); + listView->setSelectionModeExt( KListView::Single ); + + m_idCounter = KSayItGlobal::item_initial_id; + m_stopped = false; + m_currentItem = m_rootItem; + m_parasaxparser = ParaSaxParser::Instance(); + m_editMode = false; + m_changedContent = QString::null; + + m_contextmenuhandler = NULL; + m_contextmenu = NULL; +} + + +DocTreeViewImpl::~DocTreeViewImpl() +{ + if ( m_rootItem ) + delete m_rootItem; + delete m_parasaxparser; + if ( m_contextmenuhandler ) + delete m_contextmenuhandler; +} + + +void DocTreeViewImpl::enableContextMenus( bool enabled ) +{ + if ( enabled ){ + m_contextmenuhandler = new ContextMenuHandler(this, "contextmenuhandler"); + } else { + if ( m_contextmenuhandler ) + delete m_contextmenuhandler; + m_contextmenuhandler = NULL; + } +} + + +void DocTreeViewImpl::clear() +{ + kdDebug(100200) << "DocTreeViewImpl::clear()" << endl; + m_url = KURL(); + + if ( m_rootItem ) + delete m_rootItem; + + // inform BookmarkHandler + // + emit signalSetBookmarkFilename( QString::null ); + + listView->clear(); + m_rootItem = new RobDocument( listView, i18n("unnamed") ); + m_idCounter = KSayItGlobal::item_initial_id; + m_stopped = false; + m_currentItem = static_cast<ListViewInterface*>(m_rootItem); +} + + +void DocTreeViewImpl::createEmptyDocument() +{ + kdDebug(100200) << "DocTreeViewImpl::createEmptyDocument()" << endl; + // create empty document + QByteArray data; + QTextStream wrapped(data, IO_ReadWrite); + wrapped.setEncoding(QTextStream::UnicodeUTF8); + + wrapped << "<?xml version=\"1.0\" ?>" << endl; + wrapped << "<!--" << endl; + wrapped << "!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN\" \"dtd/kdex.dtd\"" << endl; + wrapped << "-->" << endl; + + QString header(data); + m_parasaxparser->setProcessingInstruction( header ); + + wrapped << "<book>" << endl; + wrapped << "<bookinfo>" << endl; + wrapped << "<title><![CDATA[" << i18n("Empty Document") << "]]></title>" << endl; + wrapped << "<authorgroup>" << endl; + wrapped << "<author>" << endl; + wrapped << "<firstname>KSayIt</firstname>" << endl; + wrapped << "<surname>Wrapper</surname>" << endl; + wrapped << "</author>" << endl; + wrapped << "</authorgroup>" << endl; + wrapped << "<copyright>" << endl; + wrapped << "<year>2005</year>" << endl; + wrapped << "<holder>Robert Vogl</holder>" << endl; + wrapped << "</copyright>" << endl; + wrapped << "</bookinfo>" << endl; + wrapped << "<chapter>" << endl; + wrapped << "<title><![CDATA[" << i18n("Untitled") << "]]></title>" << endl; + wrapped << "<para>" << endl; + wrapped << ""; + wrapped << "</para>" << endl; + wrapped << "</chapter>" << endl; + wrapped << "</book>" << endl; + + QDomDocument domTree; + if ( ! domTree.setContent( data ) ){ + kdDebug(100200) << "Kein gueltiges Dokument!!" << endl; + }; + // inform BookmarkHandler + emit signalSetBookmarkFilename( i18n("Untitled") ); + + QDomElement root = domTree.documentElement(); + QDomNode node; + if( root.tagName().lower() == "book" ){ // DocBook + DocbookParser docbookparser(m_contextmenuhandler); + docbookparser.parseBook(root , m_rootItem); + m_idCounter = docbookparser.getIdCounter(); + } + + // Initial view + m_currentItem = static_cast<ListViewInterface*>( listView->lastItem() ); + listView->setSelected( m_currentItem, true ); + listView->ensureItemVisible( m_currentItem ); + slotItemClicked( m_currentItem ); +} + + +void DocTreeViewImpl::openFile(const KURL &url) +{ + kdDebug(100200) << "DocTreeViewImpl::openFile(" << url.path() << ")" << endl; + + m_url = url; + // open file + QString err; + QFile file( url.path() ); + if( !file.open(IO_ReadOnly) ){ + err = i18n("Unable to open File."); + throw(err); + } + QDomDocument domTree; + // check document + if( domTree.setContent(&file) ){ + // extract Header + file.reset(); + QString header = QString::null; + QString line; + int offset; + file.readLine( line, file.size() ); + while( !file.atEnd() && (offset = line.find("<book", 0, false)) < 0 ){ + header += line; + file.readLine( line, file.size() ); + } + file.close(); + header += line.left( offset ); + kdDebug(100200) << "### Header: " << endl << header << endl; + m_parasaxparser->setProcessingInstruction( header ); + // inform BookmarkHandler about the opened file + emit signalSetBookmarkFilename( url.fileName() ); + } else { + // File is not a valid XML-File. Wrap it + file.reset(); + QByteArray data; + QTextStream wrapped(data, IO_ReadWrite); + wrapped.setEncoding(QTextStream::UnicodeUTF8); + + wrapped << "<?xml version=\"1.0\" ?>" << endl; + wrapped << "<!--" << endl; + wrapped << "!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN\" \"dtd/kdex.dtd\"" << endl; + wrapped << "-->" << endl; + + QString header(data); + kdDebug(100200) << "Header (Wrapper): " << endl << header << endl; + m_parasaxparser->setProcessingInstruction( header ); + + wrapped << "<book>" << endl; + wrapped << "<bookinfo>" << endl; + wrapped << "<title><![CDATA[" << url.path() << "]]></title>" << endl; + wrapped << "<authorgroup>" << endl; + wrapped << "<author>" << endl; + wrapped << "<firstname>KSayIt</firstname>" << endl; + wrapped << "<surname>Wrapper</surname>" << endl; + wrapped << "</author>" << endl; + wrapped << "</authorgroup>" << endl; + wrapped << "<copyright>" << endl; + wrapped << "<year>2005</year>" << endl; + wrapped << "<holder>Robert Vogl</holder>" << endl; + wrapped << "</copyright>" << endl; + wrapped << "</bookinfo>" << endl; + wrapped << "<chapter>" << endl; + wrapped << "<title><![CDATA[" << i18n("Plain File") << "]]></title>" << endl; + wrapped << "<para><![CDATA["; + wrapped << QString( file.readAll() ); + wrapped << "]]></para>" << endl; + wrapped << "</chapter>" << endl; + wrapped << "</book>" << endl; + file.close(); + + // Try again + if (! domTree.setContent(data)){ + err = i18n("Failed wrapping the file into XML."); + throw(err); + } + emit signalSetBookmarkFilename( i18n("Plain File") ); + } + + // check if correct document type + QDomElement root = domTree.documentElement(); + if( root.tagName().lower() == "book" ){ // DocBook + DocbookParser docbookparser(m_contextmenuhandler); + docbookparser.parseBook(root , m_rootItem); + m_idCounter = docbookparser.getIdCounter(); + } else { + err = i18n("The file is of type %1, 'book' expected.").arg(root.tagName() ); + throw(err); + } + + // Initial view + listView->setSelected( m_rootItem, true ); + slotItemClicked( m_rootItem ); +} + + +void DocTreeViewImpl::saveFile() +{ + kdDebug(100200) << "DocTreeViewImpl::saveFile()" << endl; + + makeCurrentNodePersistent(); + + QString err; + + if ( m_url.isEmpty() ){ // file has no name, ask user + QString usershome( getenv("HOME") ); + m_url = KFileDialog::getSaveURL(usershome, "*.docbook", this, i18n("Save File")); + } + if ( m_url.isEmpty() ) // dialog cancelled + return; + if ( !m_url.isValid() ){ + err = i18n("The given URL is invalid. Try 'File save as...' instead."); + throw( err ); + } + if ( m_url.isLocalFile() ){ + QFile file( m_url.path() ); + if ( !file.open(IO_WriteOnly) ){ + err = i18n("Unable open file to write."); + throw( err ); + } + // write file + QTextStream doc(&file); + doc.setEncoding(QTextStream::UnicodeUTF8); + + doc << "<?xml version=\"1.0\" ?>" << endl; + doc << "<!--" << endl; + doc << "!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN\" \"dtd/kdex.dtd\"" << endl; + doc << "-->" << endl; + + DocbookGenerator generator; + generator.writeBook( doc, m_rootItem ); + + // update root item + m_rootItem->setText(0, m_url.fileName() ); + m_rootItem->setValue(KSayItGlobal::RTFHEADER, m_url.fileName()); + m_rootItem->setValue(KSayItGlobal::SPEAKERHEADER, m_url.fileName()); + file.close(); + } else { + err = i18n("Save operation currently works on local files only."); + throw( err ); + } + // inform BookmarkHandler + emit signalChangeBookmarkFilename( m_url.fileName() ); + slotItemClicked( m_currentItem ); +} + + +void DocTreeViewImpl::saveFileAs() +{ + kdDebug(100200) << "DocTreeViewImpl::saveFileAs()" << endl; + QString err; + + makeCurrentNodePersistent(); + + m_url = KFileDialog::getSaveURL(QString::null, "*.docbook", this, i18n("Save File As")); + if ( m_url.isEmpty() ) // dialog cancelled + return; + if ( !m_url.isValid() ){ + err = i18n("The given URL is invalid."); + throw( err ); + } + if ( m_url.isLocalFile() ){ + QFile file( m_url.path() ); + if ( !file.open(IO_WriteOnly) ){ + err = i18n("Unable open file to write."); + throw( err ); + } + + // write file + QTextStream doc(&file); + doc.setEncoding(QTextStream::UnicodeUTF8); + + doc << "<?xml version=\"1.0\" ?>" << endl; + doc << "<!--" << endl; + doc << "!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN\" \"dtd/kdex.dtd\"" << endl; + doc << "-->" << endl; + + DocbookGenerator generator; + generator.writeBook( doc, m_rootItem ); + + // update root item + m_rootItem->setText(0, m_url.fileName() ); + m_rootItem->setValue(KSayItGlobal::RTFHEADER, m_url.fileName()); + m_rootItem->setValue(KSayItGlobal::SPEAKERHEADER, m_url.fileName()); + + file.close(); + } else { + err = i18n("Save operation currently works on local files only."); + throw( err ); + } + // inform BookmarkHandler + emit signalChangeBookmarkFilename( m_url.fileName() ); + slotItemClicked( m_currentItem ); +} + + +void DocTreeViewImpl::setEditMode(bool mode) +{ + m_editMode = mode; + bool editable = ( m_currentItem->getValue(KSayItGlobal::ISEDITABLE) ).toBool(); + if ( editable && mode ){ + emit signalEnableTextedit( true ); + slotItemClicked( m_currentItem ); + return; + } + + makeCurrentNodePersistent(); + slotItemClicked( m_currentItem ); + + emit signalEnableTextedit( false ); +} + + +void DocTreeViewImpl::makeToSingleLine( QString &content ) +{ + // canonify string + content.replace( QRegExp("\n"), "" ); // remove Newlines + content.replace( QRegExp(" {2,}"), " " ); // remove multiple spaces + content.replace( QRegExp("[\t|\r]{1,}"), ""); // remove Tabs +} + + +QString DocTreeViewImpl::selectItemByID(const QString &ID, const QString title) +{ + kdDebug(100200) << "DocTreeViewImpl::selectItemByID(" << ID << ")" << endl; + + if ( ID.isNull() ) + return QString::null; + + QString sTitle = title.lower(); + QString err = QString::null; + + /** + * Search on structure (URL) + * e.g. 1=RobDokument|1=BookInfo|1=KeywordSet|2=Keyword + */ + QStringList partList; + partList = QStringList::split("|", ID); + QStringList::Iterator it = partList.begin(); + it++; // skip first element (allways RobDocument) + int childNum = 0; + QString childType = QString::null; + ListViewInterface *item = m_rootItem; + bool hit = false; + + for (; it!=partList.end(); ++it){ + kdDebug(100200) << "Part: " << (*it) << endl; + if ( !item ) + break; // expected item does not exist + item = static_cast<ListViewInterface*>( item->firstChild() ); + if ( item ){ + childNum = ((*it).section('=', 0, 0)).toInt(); + childType = (*it).section('=', 1, 1); + childType = childType.lower(); + for (int i=1; i<childNum; i++){ + item = static_cast<ListViewInterface*>( item->nextSibling() ); + if ( !item ) + break; // expected item does not exist + } + if ( !item ) + break; // expected item does not exist + QString type = ( item->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + type = type.lower(); + if ( childType != type ) + break; // structure has been changed + } + } + + if ( item ){ + QString itemTitle = getItemTitle( item ); + itemTitle = itemTitle.lower(); + if ( sTitle.left(itemTitle.length()) == itemTitle ) + // Title made unique by KDE by appending "(2)", "(3)"... + hit = true; + } + + if ( !hit ){ + /** + * Not found, search on title + */ + // walk trough the entire tree and try to find an item + // with the given title. + item = NULL; + QListViewItemIterator sit( m_rootItem ); + QString itemTitle = QString::null; + while ( sit.current() ) { + item = static_cast<ListViewInterface*>(sit.current()); + if ( !item ) + break; // expected item does not exist + itemTitle = getItemTitle( item ); + itemTitle = itemTitle.lower(); + if ( sTitle.left(itemTitle.length()) == itemTitle ){ + hit = true; + err = i18n("Maybe the structure of the document has been changed. Please check if this bookmark is still valid."); + break; + } + ++sit; + } + } + + // still not found => Failure + if ( !hit ){ + err = i18n("Bookmark not found. Maybe the file content or the bookmark URL has been changed."); + return err; + } + + // show + bool editable = ( item->getValue(KSayItGlobal::ISEDITABLE) ).toBool(); + if ( editable ) + makeCurrentNodePersistent(); + + listView->setSelected( item, true ); + listView->ensureItemVisible( item ); + slotItemClicked( item ); + return err; +} + + +void DocTreeViewImpl::slotItemClicked(QListViewItem *item) +{ + kdDebug(100200) << "DocTreeViewImpl::slotItemClicked()" << endl; + + if ( item != m_currentItem ){ + makeCurrentNodePersistent(); + } + + if ( item ){ + m_currentItem = static_cast<ListViewInterface*>(item); + QString str = QString::null; + QTextStream msg(&str, IO_ReadWrite); + msg.setEncoding(QTextStream::UnicodeUTF8); + + // check if item has a child and check state + // of Edit Mode. + bool editable = ( m_currentItem->getValue(KSayItGlobal::ISEDITABLE) ).toBool() && m_editMode; + + emit signalEnableTextedit( editable ); + recursiveTextCollector( m_currentItem, msg, !editable ); + emit signalContentChanged( str ); + + // Create Bookmark-ID depending on the location of the item + // within the tree + QString idstring = QString::null; + QTextStream id(&idstring, IO_ReadWrite); + id.setEncoding(QTextStream::UnicodeUTF8); + id << "1=RobDocument"; + recursiveBuildItemIdentifier( m_currentItem, id ); + + // inform the Bookmark Manager about the new item. + QString title = getItemTitle( m_currentItem ); + emit signalNotifyBookmarkManager(idstring, title); + } +} + + +void DocTreeViewImpl::slotRightButtonPressed(QListViewItem *item, const QPoint &pos, int) +{ + kdDebug(100200) << "DocTreeViewImpl::slotRightButtonPressed()" << endl; + slotItemClicked( item ); + + if ( !m_currentItem ) + return; + + m_contextmenu = m_contextmenuhandler->getPopupMenu( m_currentItem ); + if ( !m_contextmenu ) + return; + + m_contextmenu->exec( pos ); +} + + +void DocTreeViewImpl::recursiveBuildItemIdentifier(ListViewInterface* item, QTextStream &idstring) +{ + kdDebug(100200) << "DocTreeViewImpl::recursiveBuildItemIdentifier()" << endl; + + if ( !item ) + return; + + // 1. Do we have a parent (=parentItem)? + // If no -> return, if yes -> recursive call + ListViewInterface *parentItem = NULL; + parentItem = static_cast<ListViewInterface*>( item->parent() ); + if ( parentItem ){ + recursiveBuildItemIdentifier( parentItem, idstring ); + } else { + // break recursion + return; + } + + // 2. Which child of the parentItem are we? Append no. to idstring. + int childno = 0; + QString itemID = item->text(3); + ListViewInterface *i = static_cast<ListViewInterface*>( parentItem->firstChild() ); + while( i ){ + childno++; + if ( i->text(3) == itemID ) + break; + i = static_cast<ListViewInterface*>( i->nextSibling() ); + } + idstring << "|" << childno; + + // 3. Who are we? Append ID to idstring. + QString itemType = ( item->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + idstring << "=" << itemType; +} + + +QString DocTreeViewImpl::getItemTitle( ListViewInterface *item ) +{ + if ( !item ) + return QString::null; + + QString col0 = item->text(0); + QString title = QString::null; + // if ( col0 == i18n("Paragraph") ){ // better to use XmlContextName? + if( (item->getValue(KSayItGlobal::XMLCONTEXTNAME)).toString() == i18n("Paragraph") ){ + title = ( item->getValue(KSayItGlobal::SPEAKERDATA) ).toString().left(32); + + // canonify string + title.replace( QRegExp("^( |\t|\n)+"), ""); + title.replace( QRegExp("( |\t|\n)$+"), ""); + } else { + title = col0.left(32); + } + return title; +} + + +void DocTreeViewImpl::recursiveTextCollector(ListViewInterface* item, QTextStream &msg, bool header) +{ + kdDebug(100200) << "DocTreeViewImpl::recursiveTextCollector()" << endl; + + QString text; + if ( header ){ + // if header==true get Headers + msg << ( item->getValue(KSayItGlobal::RTFHEADER) ).toString(); + text = ( item->getValue(KSayItGlobal::RTFDATA ) ).toString(); + } else { + // get raw data (Edit Mode) + text = ( item->getValue(KSayItGlobal::RAWDATA) ).toString(); + } + if ( !text.isNull() ) + msg << text; + + // check if current item has a child + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + + while( i ){ + recursiveTextCollector( i, msg, header ); + i = static_cast<ListViewInterface*>(i->nextSibling()); + } +} + + +void DocTreeViewImpl::sayActiveNodeAndChilds() +{ + kdDebug(100200) << "DocTreeViewImpl::sayActiveNodeAndChilds()" << endl; + + m_stopped = false; + if ( !(m_currentItem->firstChild()) ){ + // current item has no childs. It may be changed. + makeCurrentNodePersistent(); + } + + recursiveSayNodes( m_currentItem ); + emit signalAllNodesProcessed(); +} + + +void DocTreeViewImpl::recursiveSayNodes(ListViewInterface* item) +{ + kdDebug(100200) << "DocTreeViewImpl::recursiveSayNodes()" << endl; + + QString str; + QTextStream msg(&str, IO_ReadWrite); + msg.setEncoding(QTextStream::UnicodeUTF8); + + msg << ( item->getValue(KSayItGlobal::SPEAKERHEADER) ).toString(); + msg << ( item->getValue(KSayItGlobal::SPEAKERDATA) ).toString() << "\n" << endl; + + // request say task + if ( !m_stopped ){ + emit signalSetText( str ); + } else { + return; + } + + // check if current item has a child + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + while( i ){ + recursiveSayNodes( i ); + i = static_cast<ListViewInterface*>(i->nextSibling()); + } +} + + +void DocTreeViewImpl::stop() +{ + kdDebug(100200) << "DocTreeViewImpl::stop()" << endl; + m_stopped = true; +} + + +void DocTreeViewImpl::setNodeContent(QString &text) +{ + kdDebug(100200) << "DocTreeViewImpl::setNodeContent()" << endl; + m_changedContent = text; +} + + +void DocTreeViewImpl::makeCurrentNodePersistent() +{ + kdDebug(100200) << "DocTreeViewImpl::slotMakeCurrentNodePersistent()" << endl; + if ( m_changedContent.isNull() ) + return; // no changes were happen + + int maxlines = ( m_currentItem->getValue(KSayItGlobal::MAXLINES) ).toInt(); + if ( maxlines == 1 ){ // Item with max. 1 line. + makeToSingleLine( m_changedContent ); + } + + m_currentItem->setValue( KSayItGlobal::RAWDATA, m_changedContent ); + m_currentItem->setValue( KSayItGlobal::RTFDATA, m_changedContent ); + m_currentItem->setValue( KSayItGlobal::SPEAKERDATA, m_changedContent ); + + m_changedContent = QString::null; +} + +/** replaced by slotRightButtonPressed() + */ +// void DocTreeViewImpl::contextMenuEvent(QContextMenuEvent *e) +// { +// kdDebug(100200) << "DocTreeViewImpl::contextMenuEvent()" << endl; +// +// if ( !m_currentItem ) +// return; +// +// m_contextmenu = m_contextmenuhandler->getPopupMenu( m_currentItem ); +// if ( !m_contextmenu ) +// return; +// +// m_contextmenu->exec( e->globalPos() ); +// } + + +/****************************************** + * Context-Menu functions + ******************************************/ + +void DocTreeViewImpl::slotRenameItem() +{ + kdDebug(100200) << "DocTreeViewImpl::slotRenameItem()" << endl; + + if (!m_currentItem) + return; + + bool responseOK; + QString newname; + newname = KInputDialog::getText( + i18n("Rename Item"), + i18n("Please enter the new name of the item:"), + m_currentItem->text(0), + &responseOK, + this, + "queryNewItemName" + ); + if ( !responseOK ) + return; + + // update TreeView + m_currentItem->setText(0, newname); + m_currentItem->setValue( KSayItGlobal::RTFHEADER, newname ); + m_currentItem->setValue( KSayItGlobal::SPEAKERHEADER, newname ); +} + + +void DocTreeViewImpl::slotDeleteItem() +{ + kdDebug(100200) << "DocTreeViewImpl::slotDeleteItem()" << endl; + + ListViewInterface *itemToDelete = m_currentItem; + ListViewInterface *parentItem = NULL; + parentItem = static_cast<ListViewInterface*>(itemToDelete->parent()); + if ( !parentItem ) + return; // delete only items with parent + + // try to delete bookmark + QString url = QString::null; + QTextStream id(&url, IO_ReadWrite); + id.setEncoding(QTextStream::UnicodeUTF8); + id << "ksayit://1=RobDocument"; + recursiveBuildItemIdentifier( itemToDelete, id ); + QString title = getItemTitle( itemToDelete ); + emit signalDeleteBookmark( url, title ); + + // remove TreeView item + delete itemToDelete; + + // reindex entire remaining tree + ListViewInterface *item = NULL; + m_idCounter = KSayItGlobal::item_initial_id; + QListViewItemIterator itr( m_rootItem ); + while ( itr.current() ) { + item = static_cast<ListViewInterface*>(itr.current()); + item->setText(3, QString("%1").arg(++m_idCounter).rightJustify(8,'0') ); + ++itr; + } + + // show + m_rootItem->sort(); + listView->setSelected( parentItem, true ); + listView->ensureItemVisible( parentItem ); + slotItemClicked( parentItem ); +} + + +void DocTreeViewImpl::slotNewBookInfo() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "RobDocument" ){ + int newIndex = newIndexFirstChild(); + Overview *overview = new Overview( m_currentItem, NULL, i18n("Overview") ); + overview->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + m_contextmenuhandler->registerPopupMenu( overview ); + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewChapter() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "RobDocument" ){ + int newIndex = newIndexLastChild(); + Chapter *chapter = new Chapter( m_currentItem, NULL, i18n("Chapter") ); + chapter->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + QString newTitle = i18n("New Chapter Title"); + chapter->setText(0, newTitle ); + chapter->setValue(KSayItGlobal::RTFHEADER, newTitle ); + chapter->setValue(KSayItGlobal::SPEAKERHEADER, newTitle ); + + m_contextmenuhandler->registerPopupMenu( chapter ); + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewKeywordSet() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "BookInfo" ){ + // New TreeView item + int newIndex = newIndexFirstChild(); + KeywordSet *keywordset = new KeywordSet(m_currentItem, NULL, i18n("Keywords")); + keywordset->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + m_contextmenuhandler->registerPopupMenu( keywordset ); + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewKeyword() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "KeywordSet" ){ + // New TreeView item + int newIndex = newIndexLastChild(); + Keyword *keyword = new Keyword(m_currentItem, NULL, i18n("Keyword")); + keyword->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + QString newKeyword = i18n("New Keyword"); + keyword->setText(0, newKeyword ); + keyword->setValue(KSayItGlobal::RAWDATA, newKeyword); + keyword->setValue(KSayItGlobal::RTFDATA, newKeyword); + keyword->setValue(KSayItGlobal::SPEAKERDATA, newKeyword); + + m_contextmenuhandler->registerPopupMenu( keyword ); + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewAbstract() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "BookInfo" ){ + // New TreeView item + int newIndex = newIndexLastChild(); + Abstract *abstract = new Abstract(m_currentItem, NULL, i18n("Abstract")); + abstract->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + m_contextmenuhandler->registerPopupMenu( abstract ); + + // add a new Para-Element + ListViewInterface *backup = m_currentItem; + m_currentItem = abstract; + slotNewParagraph(); + m_currentItem = backup; + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewAuthorGroup() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "BookInfo" ){ + // New TreeView item + int newIndex = newIndexFirstChild(); + AuthorGroup *authorgroup = new AuthorGroup(m_currentItem, NULL, i18n("Author(s)")); + authorgroup->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + m_contextmenuhandler->registerPopupMenu( authorgroup ); + + // add a new Author-Element + ListViewInterface *backup = m_currentItem; + m_currentItem = authorgroup; + slotNewAuthor(); + m_currentItem = backup; + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewAuthor() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "AuthorGroup" ){ + // New TreeView item + int newIndex = newIndexLastChild(); + Author *author = new Author(m_currentItem); + author->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + author->setText(0, i18n("Author") ); + QString newAuthor = i18n("Firstname Surname"); + author->setText(1, newAuthor ); + author->setValue( KSayItGlobal::RAWDATA, newAuthor ); + author->setValue( KSayItGlobal::RTFDATA, newAuthor ); + author->setValue( KSayItGlobal::SPEAKERDATA, newAuthor ); + + m_contextmenuhandler->registerPopupMenu( author ); + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewDate() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "BookInfo" ){ + // New TreeView item + int newIndex = newIndexLastChild(); + Date *date = new Date(m_currentItem, NULL, i18n("Date")); + date->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + // get current date + QString today; + today = KGlobal::locale()->formatDate(QDate::currentDate(Qt::LocalTime), true); + date->setText( 1, today); + date->setValue( KSayItGlobal::RAWDATA, today ); + date->setValue( KSayItGlobal::RTFDATA, today ); + date->setValue( KSayItGlobal::SPEAKERDATA, today ); + + m_contextmenuhandler->registerPopupMenu( date ); + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewReleaseInfo() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "BookInfo" ){ + // New TreeView item + int newIndex = newIndexLastChild(); + ReleaseInfo *relinfo = new ReleaseInfo(m_currentItem, NULL, i18n("Release")); + relinfo->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + QString newRelease = "0.0.0"; + relinfo->setText( 1, newRelease ); + relinfo->setValue( KSayItGlobal::RAWDATA, newRelease ); + relinfo->setValue( KSayItGlobal::RTFDATA, newRelease ); + relinfo->setValue( KSayItGlobal::SPEAKERDATA, newRelease ); + + m_contextmenuhandler->registerPopupMenu( relinfo ); + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewTitle() +{ + +} + +void DocTreeViewImpl::slotNewParagraph() +{ +/* // Create Null element + QDomElement parentElement = QDomElement(); + + NodeList_type list; + list.clear(); + m_currentItem->getNodes( list ); + parentElement = (list.front()).toElement(); + + if ( parentElement.isNull() ) + return; +*/ + // New TreeView item + int newIndex = newIndexLastChild(); + Para *para = new Para(m_currentItem, NULL, i18n("Paragraph")); + para->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + m_contextmenuhandler->registerPopupMenu( para ); + + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewSection_1() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "Chapter" ){ + int newIndex = newIndexLastChild(); + Sect1 *sect1 = new Sect1(m_currentItem, NULL, i18n("Section Level 1")); + sect1->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + QString newTitle = i18n("New Section Title"); + sect1->setValue( KSayItGlobal::RTFHEADER, newTitle ); + sect1->setValue( KSayItGlobal::SPEAKERHEADER, newTitle ); + + m_contextmenuhandler->registerPopupMenu( sect1 ); + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewSection_2() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "Sect1" ){ + int newIndex = newIndexLastChild(); + Sect2 *sect2 = new Sect2(m_currentItem, NULL, i18n("Section Level 2")); + sect2->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + QString newTitle = i18n("New Section Title"); + sect2->setValue( KSayItGlobal::RTFHEADER, newTitle ); + sect2->setValue( KSayItGlobal::SPEAKERHEADER, newTitle ); + + m_contextmenuhandler->registerPopupMenu( sect2 ); + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewSection_3() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "Sect2" ){ + int newIndex = newIndexLastChild(); + Sect3 *sect3 = new Sect3(m_currentItem, NULL, i18n("Section Level 3")); + sect3->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + QString newTitle = i18n("New Section Title"); + sect3->setValue( KSayItGlobal::RTFHEADER, newTitle ); + sect3->setValue( KSayItGlobal::SPEAKERHEADER, newTitle ); + + m_contextmenuhandler->registerPopupMenu( sect3 ); + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewSection_4() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "Sect3" ){ + int newIndex = newIndexLastChild(); + Sect4 *sect4 = new Sect4(m_currentItem, NULL, i18n("Section Level 4")); + sect4->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + QString newTitle = i18n("New Section Title"); + sect4->setValue( KSayItGlobal::RTFHEADER, newTitle ); + sect4->setValue( KSayItGlobal::SPEAKERHEADER, newTitle ); + + m_contextmenuhandler->registerPopupMenu( sect4 ); + } + m_rootItem->sort(); +} + +void DocTreeViewImpl::slotNewSection_5() +{ + QString whoAmI = ( m_currentItem->getValue(KSayItGlobal::XMLCONTEXTNAME) ).toString(); + if ( whoAmI == "Sect4" ){ + int newIndex = newIndexLastChild(); + Sect5 *sect5 = new Sect5(m_currentItem, NULL, i18n("Section Level 5")); + sect5->setText(3, QString("%1").arg(newIndex).rightJustify(8,'0') ); + + QString newTitle = i18n("New Section Title"); + sect5->setValue( KSayItGlobal::RTFHEADER, newTitle ); + sect5->setValue( KSayItGlobal::SPEAKERHEADER, newTitle ); + + m_contextmenuhandler->registerPopupMenu( sect5 ); + } + m_rootItem->sort(); +} + +int DocTreeViewImpl::newIndexFirstChild() +{ + kdDebug(100200) << "DocTreeViewImpl::newIndexFirstChild()" << endl; + + int currentIndex = (m_currentItem->text(3)).toInt(); + + // walk trough the entire tree and increment all + // indices greater than currentIndex + ListViewInterface *item = NULL; + int itemIndex; + QListViewItemIterator it( m_rootItem ); + while ( it.current() ) { + item = static_cast<ListViewInterface*>(it.current()); + itemIndex = (item->text(3)).toInt(); + if ( itemIndex > currentIndex ){ + item->setText(3, QString("%1").arg(itemIndex+1).rightJustify(8,'0') );; + } + ++it; + } + + m_idCounter++; + currentIndex += 1; + return currentIndex; +} + + +int DocTreeViewImpl::newIndexLastChild() +{ + kdDebug(100200) << "DocTreeViewImpl::newIndexLastChild()" << endl; + + // find highest index of the subtree with + // m_currentItem as root + int lastIndex = 0; + findHighestIndex( m_currentItem, lastIndex ); + kdDebug(100200) << "Letzter Index: " << lastIndex << endl; + + // walk trough the entire tree and increment all + // indices greater than lastIndex + int itemIndex; + ListViewInterface *item; + QListViewItemIterator it( m_rootItem ); + while ( it.current() ) { + item = static_cast<ListViewInterface*>(it.current()); + itemIndex = (item->text(3)).toInt(); + if ( itemIndex > lastIndex ){ + item->setText(3, QString("%1").arg(itemIndex+1).rightJustify(8,'0') ); + } + ++it; + } + + m_idCounter++; + lastIndex += 1; + return lastIndex; +} + + +void DocTreeViewImpl::findHighestIndex(ListViewInterface* item, int &index) +{ + int currentIndex = (item->text(3)).toInt(); + index = currentIndex > index ? currentIndex : index; + + ListViewInterface *i = static_cast<ListViewInterface*>(item->firstChild()); + while( i ){ + findHighestIndex(i, index); + i = static_cast<ListViewInterface*>(i->nextSibling()); + } +} + diff --git a/ksayit/src/doctreeviewimpl.h b/ksayit/src/doctreeviewimpl.h new file mode 100644 index 0000000..4ad0c38 --- /dev/null +++ b/ksayit/src/doctreeviewimpl.h @@ -0,0 +1,191 @@ +// +// C++ Interface: doctreeviewimpl +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef DOCTREEVIEWIMPL_H +#define DOCTREEVIEWIMPL_H + +// Qt includes +#include <qstring.h> + +// KDE includes +#include <kurl.h> +#include <klistview.h> +#include <kpopupmenu.h> + +// App specific includes +#include "Types.h" +#include "DocTreeView.h" + +// forward declarations +class ParaSaxParser; +class ContextMenuHandler; + + +/** +This class implements the TreeView object.\n +It takes a XML/DocBook file, parses it and builds up a hierarchical +\p QListView structure corresponding to the structure of the document. +The objective of this class is to maintain the document and provide +all required methods to access or manipulate its content. +@author Robert Vogl +*/ +class DocTreeViewImpl : public DocTreeView +{ +public: + DocTreeViewImpl(QWidget* parent=0, const char* name=0, WFlags fl=0); + + ~DocTreeViewImpl(); + + /** + * Tries to open and parse the given file. If the file is not identified as a + * valid XML/DocBook file, it will be packed as a \p CDATA block into a \p para element + * of a simple DocBook'ish XML file. + * \param url The URL of the file. + */ + void openFile(const KURL &url); + + /** + * Saves the document to a XML file. + */ + void saveFile(); + + /** + * Saves the document to a XML file and allows the user to define a name. + */ + void saveFileAs(); + + /** + * Cleans up the interal document data structures. + */ + void clear(); + + /** + * Creates an empty XML document that conatins one editable DocBook \p Paragraph. + * Usually called after clean() and initial startup. + */ + void createEmptyDocument(); + + /** + * Stores the given text but does not make the new content + * persistent. + * \param text The content of the TextEdit view. + */ + void setNodeContent(QString &text); + + /** + * Starting from the current selected node it travels recursively + * through all childs and collects the content of all corresponding + * DOM nodes. After sending the text to the TTS system the speech synthesis + * process will be started. + */ + void sayActiveNodeAndChilds(); + + /** + * Signals a stop-talking-request from the user. + */ + void stop(); + + /** + * Controls the Edit Mode. + * \param mode If true, Edit Mode ON,\n if false, Edit Mode OFF. + */ + void setEditMode(bool mode); + + /** + * Sets the item active designated by the ID. + * \param ID The ID (column 3) of the TreeView item. + * \returns <tt>QString::null</tt> if the operation was successfull,\n + * an error message, if the item was not found. + */ + QString selectItemByID(const QString &ID, const QString title); + + /** + * Enables/disables the contextmenus + */ + void enableContextMenus( bool enabled ); + +public slots: + void slotRenameItem(); // reimplemented from base classes + void slotDeleteItem(); + void slotNewBookInfo(); + void slotNewChapter(); + void slotNewKeywordSet(); + void slotNewKeyword(); + void slotNewAbstract(); + void slotNewAuthorGroup(); + void slotNewAuthor(); + void slotNewDate(); + void slotNewReleaseInfo(); + void slotNewTitle(); + void slotNewParagraph(); + void slotNewSection_1(); + void slotNewSection_2(); + void slotNewSection_3(); + void slotNewSection_4(); + void slotNewSection_5(); + +protected slots: + /** + * Reimplemented from base class. + * Called whenever the active node has been changed.\n + * Makes the former selected item persistent (maybe it has + * been changed).\n + * Displays the content of the selected Node either in RTF or + * plain text format (depending on the Edit Mode flag, childs + * present or not).\n + * Informs the BookmarkManager about the new item. + * + * \param item The new active item of the TreeView. + */ + void slotItemClicked(QListViewItem *item); + + /** + * Reimplemented from base class. + * Called when the right button was pressed. + * \param item The new active item of the TreeView. + */ + void slotRightButtonPressed(QListViewItem *item, const QPoint &pos, int); + + /** + * Reimplemented from QWidget class. + */ + // void contextMenuEvent(QContextMenuEvent *e); + +private: // Methods + void recursiveTextCollector(ListViewInterface* item, QTextStream &msg, bool header=true); + void recursiveSayNodes(ListViewInterface* item); + void recursiveBuildItemIdentifier(ListViewInterface* item, QTextStream &idstring); + void makeCurrentNodePersistent(); + int newIndexFirstChild(); + int newIndexLastChild(); + void findHighestIndex(ListViewInterface* item, int &index); + QString getItemTitle( ListViewInterface *item); + void makeToSingleLine( QString &content ); + + +private: // Attributes + ContextMenuHandler *m_contextmenuhandler; + KPopupMenu *m_contextmenu; + ListViewInterface *m_rootItem; + ListViewInterface *m_currentItem; + QString m_changedContent; + int m_idCounter; + bool m_stopped; + KURL m_url; + ParaSaxParser *m_parasaxparser; + bool m_editMode; +}; + + + + + +#endif diff --git a/ksayit/src/effectstack.cpp b/ksayit/src/effectstack.cpp new file mode 100644 index 0000000..7497847 --- /dev/null +++ b/ksayit/src/effectstack.cpp @@ -0,0 +1,65 @@ +// +// C++ Implementation: effectstack +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +// Qt includes +#include <qstringlist.h> + +// KDE includes +#include <kdebug.h> + +// App specific includes +#include "effectstack.h" +#include "fxpluginhandler.h" + +EffectStack::EffectStack(FXPluginHandler *pluginhandler, KConfig *config) + : + dispatcher(), server(), + m_pluginhandler(pluginhandler), + m_config(config) +{ +} + + +EffectStack::~EffectStack() +{ +} + +bool EffectStack::loadEffects() +{ + kdDebug(100200) << "EffectStack::loadEffects()" << endl; + + QStringList c_active; + QStringList::Iterator fx_it; + + // create filterstack + FX_Stack = server.server().outstack(); + + m_config->setGroup("Effect Stack Configuration"); + c_active = m_config->readListEntry("Activated"); + for(fx_it=c_active.begin(); fx_it!=c_active.end(); ++fx_it){ + + m_pluginhandler->activateEffect(*fx_it, &server, &FX_Stack); + + } + return true; +} + + +bool EffectStack::unloadEffects() +{ + kdDebug(100200) << "EffectStack::unloadEffects()" << endl; + // remove all effects + m_pluginhandler->deactivateEffects(&FX_Stack); + + return true; +} + diff --git a/ksayit/src/effectstack.h b/ksayit/src/effectstack.h new file mode 100644 index 0000000..0716ef7 --- /dev/null +++ b/ksayit/src/effectstack.h @@ -0,0 +1,57 @@ +// +// C++ Interface: effectstack +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef EFFECTSTACK_H +#define EFFECTSTACK_H + +// KDE includes +#include <arts/kmedia2.h> +#include <kconfig.h> + +#include <arts/kartsdispatcher.h> +#include <arts/kartsserver.h> +#include <arts/soundserver.h> + + +namespace Arts +{ + class SoundServerV2; +} +using namespace Arts; + +// forward declarations +class FXPluginHandler; + +/** +@author Robert Vogl +*/ +class EffectStack{ +public: + EffectStack(FXPluginHandler *pluginhandler=0, KConfig *config=0); + ~EffectStack(); + + // KDE::PlayObject *playobj; + KArtsDispatcher dispatcher; + KArtsServer server; + StereoEffectStack FX_Stack; + +public: //Methods + bool loadEffects(); + bool unloadEffects(); + +private: + FXPluginHandler *m_pluginhandler; + KConfig *m_config; + + +}; + +#endif diff --git a/ksayit/src/fx_setup.ui b/ksayit/src/fx_setup.ui new file mode 100644 index 0000000..60ad57d --- /dev/null +++ b/ksayit/src/fx_setup.ui @@ -0,0 +1,252 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>FX_Setup</class> +<widget class="QWidget"> + <property name="name"> + <cstring>FX_Setup</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>482</width> + <height>327</height> + </rect> + </property> + <property name="caption"> + <string>Effect Stack Setup</string> + </property> + <property name="toolTip" stdset="0"> + <string></string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout7</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel_available</cstring> + </property> + <property name="text"> + <string>Available:</string> + </property> + </widget> + <widget class="QListBox"> + <property name="name"> + <cstring>listBox_Available</cstring> + </property> + <property name="minimumSize"> + <size> + <width>150</width> + <height>170</height> + </size> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + <widget class="QToolButton"> + <property name="name"> + <cstring>toolButton_add</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="iconSet"> + <iconset>image0</iconset> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>toolButton_remove</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="iconSet"> + <iconset>image1</iconset> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel_active</cstring> + </property> + <property name="text"> + <string>Active:</string> + </property> + </widget> + <widget class="QListBox"> + <property name="name"> + <cstring>listBox_Active</cstring> + </property> + <property name="minimumSize"> + <size> + <width>150</width> + <height>170</height> + </size> + </property> + <property name="toolTip" stdset="0"> + <string>Doubleclick opens the setup dialog.</string> + </property> + </widget> + </vbox> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout8</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>pushButton_removeAll</cstring> + </property> + <property name="text"> + <string>Remove All</string> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<images> + <image name="image0"> + <data format="XPM.GZ" length="6143">789c9598c96e1e390e80ef790a23ba050375ed0b067370bcefbb637b3007925279df7f3bb61bf3eec3225995b8ba2f1301c1ff952889e226c97f7c9b3bd9dd9afbf6c797e719cc2e698e2ee069ee5b78b9bd7dfff77ffef5e797af59319795737992cc655ffff1e5ebde6c8ee6b6efef620fb4fb1bf84d06577718bb4ed8f5dcc9bf9edd43cf89fc93feabcffd743191dfff2c8ff544fe45fa9b34e6b9c8879ed33a2b95fdf567790f137e9bf0d667063f59bf9af0fe44fe6ed27f20fd79d7dafc9713fdcf3fcbc3db64fce3447e36b11f4ed6df9af4df4cf637b12fee4dd6eb26f2e7133e16ff1698753affcf9e5ba060fac9feb2a669632bfd79cf550054c6a6e7226ddb2e15f965f117568424fefb2efdb12995fdfb64fd897eb424faa7499e54327f695c287b9a8c8f130e13fb6d4fecf3d43374a136f9db497c1e4c78323fdc4ff4dd11fdba3c56b23f5c90fdb745a60c937ca167e94f591e8465ff699e77cafe43e46337e45b316189c7587499f186f82f207432de497cc572ec7f157f9634c4abd8235663ff0fe3dcf413f9ac68ca28f676b2dfaa00635a91fea48e41fd2bf156d62d28e3a2c867d075282cf1d6b454d8fcdb9fe303a57e64b1b6f820199f52d5622dfdbbd25f579db2177d288fa9f947ec4d594c6c3ff3c2c816d07eb12f41b4f5bdd497b622307d5665fe8cf7db887c6bfbe9942113fd4b327b91e463dad55d08a29fc4474e0d297bd90fe6c1eced0e27f126f9de368436df9aac9f37d8497d0389c7b282d258e2aba9c8fce3c5bfd084c19e9ba67fabf90ba9e41b9bcf58ea63db85c13e127f2d12d9f80df5779b746aff75e17260d8d4fc657d94a53e940534cafe49e7a7213f24bf1b24b33f883dda62883f67f5b7b5fd3ba9e749de9a3e28f327c8e272fea0caf7c3555ef44d0b307fb85ccf0728541e243e53607df5fc127fa6112ad3e748f707adcdaffbafc1e201c49f1940dd49bcc1b1f1e02fd96f86aded0fd55ec8fd6a3f39ffb2d00eeb751adfdc2ff9005a4f3ba04ee205ce8d83b1d4f33c1959e23b4f21dafea43ee619583d804563b3172c8facfa49fdc8f376b0bfd4a3bc1cfa49e76fdb41ff686cfa91f8230766cd57b1678eade987871affad9d17aed0f300077f48bc1525b3d68b758d4f34ffa09e0f34c697e65fc9f54ced25f5bc442ca2cacb795af6e9a3f34bfe56637e90cc57d5bcbf42e49f95f97cd3fdc9f8aac144fb41e55b1eaffd925f1562aafd24f1c9d52a537664e7e560cf1b651ae249f295ab59dd95d22ff5a8e684b37ea95f35216a7cf92363b31f8a7ff9be453ade6bfd49c9f21724be9a9c2c1e9cf8a72998d55f41eb15cf27f94f5eebc7c07863f5a48cea4fc99f86cb8f9edf78a4f57a602ffe6ac290cfa4f9dd511ad5ff1796df962f4eea754b7c7fd0f9a59e411a06fb887e50b2be7abf93f30caa9099fea21f871be9fd82e43c844831aabd24de3019eba9d81bd3d0983f9ec6faabeb89fdb108b9e9fb6a5c687df76bc696ff4ee203cb9859fd90f8403e60cd3f52bf1142a5f3b9c6183ad117c49e88ac8fc68bdce7308460f3497dc62e58fcba2be568f18f67725e2531ef443fd2f3ac084d147b6122cca7b1e587721da2facb493d2096b6faace7238de7a1d41b0acc6a6ff10ff169aef33bd18f933f0f1aff522f42124214f6bbcad1ec4f72be8474e847a99721e3ed4afcd2c3c8727f801b65d65fef7772ff60ef2476df90fd8422d441ef97d7c651f5a33be5419eee47d6f85835b6fc44676cf982521f4319539547392fd89b036f1b67761fc88c2bcd1ff761dcaafd49fc1bea515ef7c3091374bd17e5986b3feaf87660d835ae355ebcdc770307bcc587c443e0f48d9a9f97cab18c7adf3b3226bdfff913638b37a74c6c1f79e9b953e1c0fbd578927ac6d66dac1e9c1a0ff567d178384f245e79f241fe6464cdaf3563b0fbc7c6c8aabfde5f9351feddb83546635026d18fb505adfffe40b91beaa1d887ad6ffdf06a4c767f9a29f3fd56fd21f737b63e3f68a5bf3126654c95595ef591788a05cfa7fb298cad9eba4de5411ea43e717625560f9f8d53cb57a9a7b11ac663666cf90b627fb646d789bf40e2a7b7a6311ae75a6f7c635c597d91788ed80df92ef9d86b6fe34b633bcf40f28bb519b81e59fc8f609c2bc3c7c8fa1edb331eee3b527f793736de2f195bbd00f56737cce7f4fdcfa7b1ce07fa3e4e597fcd974d63abe720f5b09fddee676bc6957135b2e6a3723ef28e716dacefc362e435e3c6eab9ecaf5f4dd9ad1a5bbf5b326e4dfe873198befaf7045eddde6733e3d658fcd5cf6efc6e3cbce75e4696f871608c96df52cffad9adffd5d8ee9bae1c59e353dfb7ed287f613cc8eb7b183abbeff965e3e17ea77fefc0b1bf1a59cf43fd7b0b93b2af47567b48bde87b2d5e4f8dad3e7bc96779ef2a27c6c3fb7ef2f799bdd9d0bcf3e0d1930fdca2effcb9bff097fcedea97ccdeecf731fedadff85b7fe7effd837ff44ffed9cffc8b7ff53fbdfbfb31fecdbffb0f3fefbffb05bfe897fc32b715bfead7fcbadff09b7f1de3b758a36dbfe377fd9edf9fb4037fe88ffcf1e731acd5bbffc12b9cf8536b67f67f62bf529ff9fcd718def98d2f78aed257d66adff8d679e71cf098baffe6d0910be31870d175eedc5d8ced92db95bbe65137fd2aee56bedeb97bf76063d03dba27f7ec66637b61a957f793c778f7d6afe3def9eb879b77df6d0cb905b7e896dc32f7ac589bb955b7e6d679cc86db745bdcb7ed76dcaedb73fb124307eed01df1b763f783db893be576e61297bacce53caa70bc5357b9da35ae052f71e580df68407c11e36208e77021ed1c2ee142c678b8e29556e11a6ee016ee64cc3d3cc0233cc1b3e8ff77ed1a7897f002aff013de643fb7f00e1f300fdf610116610996b92df1af056e2bb2ceaa3f853558870dd8842d59671b766017f6601f0edcad7a88edb6ec2a3884231e710c3fe0044ee10c1248758c27c82087024aa8605f6cbdc2dad7d000fb15d915fe941f9d88fc72c0a8ba710a9fe3055efed6aee014aff1a6d70b6fd9a715dec9f77b7c501be0233ee133cef06568708657f88aec537ce338a8f01d3ff8fb3c7ec705b5759f67b8884bb86c6d0557710dd99fb881ec4fdcc26df9be83bb683ef50ef7f1000ff1088fa5fdc0133cc5334c30e5353296eebfe6586089d5900b58fb376cb0250e236ec0cfa655f6fb0a3fc80897e51b5f6db8149d0f31dac7375df82bbaa42bbaa61bba2587c77447f7f4c0d2b7fce5919ee899666e7f92db9cf3f442aff493dee89d3e689edb07fffa4e0bb4484bbcc6fe5f6b48dfdc032dd30aadd21aadd3066dd2166dd30eee61d56bf5f76364dc3e78b88337d8e2f6c6bffcb0c2af31b4fbffb5affffde797ff015a490cc1</data> + </image> + <image name="image1"> + <data format="XPM.GZ" length="6079">789c95984973dd380e80eff915aee0969a623fed524dcdc1bb1dafcfbb3d35070092bcefcf6bd7fcf781004889d57d99b09cf4671024b192ea3f7ecc9dec6ecdfdf8e3dbf30c67973cc717f834f7a37eb9bdfdf8f77ffef5e7b7ef713a1767737195cfc5dffff1edfb7436c773dbf7774d07bcf91b840ea068a9695b65e8b8d53f1dc363c713fda3f2abaf72e6d1fce9d7f9148fe6db7a65d42489ceaf3b8e8a38330ed75fe7071cf1fb88b746fb57a3fda3116f7e9d8fd723b9ad97b495af7f393a3f7d9d8fb391fec568fec3c87f34da7f6d24bf19d9375a8f3646fb57a3f9e7233ed4f8a614b7b6fe5bc71572ede753ffc765593595ca355e798d644c49c76954556da4f317345e9433b1fa7b59e54d9919878fd1feedc81ff37afe68924c725d7fe29c1a87513e8566c4f5c87feb23ff68bcb0ad0b9f7f3bca8fbd118fd6c791ffd9fcdd264daef6d1abda5fa5b13186d1fc7b9547321f95357fa324698dc3a7ce6fdabede9211df75dca46decacfb173561abfaf0a4f26c90eb79aa8cfb7cdd56793ec88f9c133f9feac7699935ea6fd0fccc5374e645954f8aa6b6f8ee769c15151a93e64f1e63db92b2da5f569cfafa3fbfe607693ec64de1f9c16a7fc4794585ca757e5ce4ad7150ff71d2441e9f15e5b899b83d9a3f4ce201936b7e3136be7f78517fe48c7e9e255d3f167b4b9d5fba3dad316a7d9419bbbf58f3296a8bb6ae55aef3132ed938a8bf28a9dddfb03fca37ed0755c9e4eb697dc44949adf637d4fe99e59839abfd65ce1e9fa0fd11cbbaf7e79a9fbfb2fac503ad37719fb3f6ebaaad7bff3c2b13b3ebaf5abcab496bfe577fc659cfb86af52be73156fd2cc5d2383cd9fadcd787fab72476ffa3d65795f6f907c1fa53e5f683d6d324a9fc3c68f54e555fafd61f19fdfca0f91ec518b5ea6f38552ed1fd81b573bfbfe513f60cea8fa8418f0759fc339480ebfc1dcb37445b1f7707367f69fdc554f97aacfd21aeabdcd7b378b6e8fd1335bf9389b0ada7f99844d8d87e70a21c63eef16a9c5d8e0bcebd3fce9493cafd89f3c6e8fd01179dfb7ea8fd3fc9c8fdc7da7f459d3cdee0cc763ed6f826286cf5992a53e5e7a76dcbf7caed03bd2fd382dc7ed478a548a59f57f321e53e7fe8deea8bc8fa03eafd9b11f5f6eaf932e90eadde2fa8fd3ecf286eb41e58eff7bc10fb525defca58ee2fb347eb2b2fc55e95b3e65f4e1419c3b5314f5aeb671a0fe946b1c9f1c2ee37c95f3b8fe647deb0db07ecf7a5fb9fb41f48f72ada4ce53abf9002337dd2f50b167bad7f1d38bbff48ed91f7159b7e507f9411f7f1b2fe99c97c7b3f64d60f7a06f55759f4f54d5a0fa5b413bb8f69c7fa6fcfc1fa49ddd7275bbdb61c35165ff07a2decbcc4767fd4516bfd51cf2bef83b2317b75fd8ae5bd60f1d5faab9abaf47c2fb45f65dc583f038d3fe675ecf9a6f52fe9c6f69e60ad17c481f5fec2869bc6fca7fd9426433fd5fd29aa3ddfe079e8bf565f6a2fa59cd7e6bf99719d98bd61ddd9eb1bf53ea4a2ceedbc61c1d9fb1569fe10d6b9e943e18c96afa0ef37aaebdaf60fdacfa89570db796efdfef2f3b2de979cd6a5e5379e193789e7d3b172c6f222535e3596fbcffab1fa838bbaf1781f1837de9f49ef2fae9a3e1e767f721335e6bf45e7be3faaffb916b6f8a8bd2cb7bd9d8ff28eeb495d37562f1bc64decf9b5ebdcf757ed3f75d4cf2793c7e21eb58f2f06d67ac44b637991d8fb4ffba3446be2ef9103e7c2fc4d8fcedeaf58fb419df6f3f97260cb9f35e7be7eb57e6af1a7c9c9e4f9c09fceb1bf0f169d2b7fdfe8fd5f17bd9c34ffba683a6b7ed755cf41fb692d09edfd41df7fb5bc571a7bff1d3b7bfe80e647ddc8792cbefbceadbdf7c2d2c0668fde1fa25c3616ffe3812dfe2bce68f1427426f337a8ffc45bbe1f9273e6fe2b0736fb7a79bf7eee5c391f3ba3d78bd69baceeef492a9cb1b17ebbed5c7bfded19b77d7fb3f76d3cccef996d3e2d3a379e3f7a3f8af7c9f21d5f7bf67ad17a6a52d1b7fb3773eefbabf60ba986c8e3addfaf4dde78bde1ddc0d6dfce8cdbd4ebcdce5ff4f341dff35d74fcfc7a7f8ab7da56bfc441f3a3b3cefbbdad8f62bfc9f5fbabb3c6f77f3716b9d97fe4ecf76d581dd8fca7fd4cacf5fb104f9dfdfe0374f6fa055baf96f9b6fead737f5f9e387bbf0afafe91d3bb3eeaf7b29cd6e5b8ec9c7a7cec7b6bd233e8fd27bb6576ffe0d4b97f9f693dc8eeb9cbd381ad3eb5dfc96eceb4e25c993f40eb5b762b7cbec65b762bbd7f6f3b57fefeb0ef2f59cdbfaf169c2baf3fcddf6e359f1f3bbb1c5e9cfbefb3d781359fc0fe7f4239b0d64fa7ed7ce1ecef25d0fba493ba3d97cedeffc28a73ff3ed3fce966bb3c1bd8f253fb6747c6211fd8fa8fd64f27f5fbecc4d9df6b41f347bf4f6dfef8fbf5ccb97f8f5a3c87efe1e9ac1f0102060a1c6a194d68c379b80897f2bbab5f73a6b3df75c275b809b7e12edc8787f0189ec273988597f01ade02fcbd4e780f1fe133cc8785b01896c2725891b11ad6c27af81936c2e65f75c2969c683bec845d993d1d8dbdb01f0ec2e1571d39d54738921d8ec34938959feeef331927c3988428c4bf74c4f29b90c85a69c8421e8a50860a0200a050d60f2060a8071d84065a38870bb8949f2bb8168d1bb80d677027fc6bdcc3033cba0ec1133cc30c5ee015dee05d34027cc027cc0b2ffc36166109965d87610556614d7ebb0e3f61433436c38968dcc196acf3227f5fc8cfb6ccd8815d986a0eecc13e1cc0211cc1319c88c6299cc144568820860452f937835c7e730805946075230621c21a1272772e7950491394a2391f468b17b2eb1a5ee2155eabce0ddee29d7cdcdd8be5e1ef073ee0231ce2133ea3d9738b2ff88a6ff88e1f2affc479190bc398c7455cc2475cc6155cc535dd671d7fe2066ee2166ee38ee8ece2b4f3013e5a64e4df3ce490e11eeee381e904c6433cc2633cc1533cc38968453e3bee7c8c09a622c930c7024b3b1b562421222492dddf49fd4035e4985223bffd7db4746e3ea00bbaa42bbaa61bcce996eee85e741ee811b6e8899e7f1b337aa157f3755767f446eff4419f344f0bb4484ba2b54c2bb44a6bf2db7eacd34fdab09806a04ddaa26ddaa15d914c698ff6e9800ee9888ee9447e67e394ce6842515f0b1487774a28a58c72d12a2412b17cecad524995fc46064b82c9db96fa1cedf29b395cb13c38a5659dcb8c0bbee42b593be76b19377ccb777ccf0f301dd5b6d43c3ff2133ff38c5ff895df64bcca7fbdf3077ff2bcec31fd6b0fe9063cf2022ff2122ff30aaff21aaff34fdea00d8aba53fdbd8eea4de543e81a67b8266386d750f53bfcd2e1cdff6f7cffef3fbffd0fd1b4fa7d</data> + </image> +</images> +<connections> + <connection> + <sender>toolButton_add</sender> + <signal>clicked()</signal> + <receiver>FX_Setup</receiver> + <slot>slotAdd()</slot> + </connection> + <connection> + <sender>toolButton_remove</sender> + <signal>clicked()</signal> + <receiver>FX_Setup</receiver> + <slot>slotRemove()</slot> + </connection> + <connection> + <sender>pushButton_removeAll</sender> + <signal>clicked()</signal> + <receiver>FX_Setup</receiver> + <slot>slotRemoveAll()</slot> + </connection> + <connection> + <sender>listBox_Active</sender> + <signal>doubleClicked(QListBoxItem*)</signal> + <receiver>FX_Setup</receiver> + <slot>slotConfigureEffect(QListBoxItem*)</slot> + </connection> +</connections> +<slots> + <slot>slotAdd()</slot> + <slot>slotRemove()</slot> + <slot>slotRemoveAll()</slot> + <slot>slotConfigureEffect(QListBoxItem*)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/ksayit/src/fxpluginhandler.cpp b/ksayit/src/fxpluginhandler.cpp new file mode 100644 index 0000000..8e6f68d --- /dev/null +++ b/ksayit/src/fxpluginhandler.cpp @@ -0,0 +1,239 @@ +// +// C++ Implementation: fxpluginhandler +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +// QT includes +#include <qdir.h> + +// KDE includes +#include <kdebug.h> +#include <kapplication.h> +#include <ktrader.h> +#include <klibloader.h> +#include <kservice.h> + +// App specific includes +#include "fxpluginhandler.h" +#include "ksayit_fxplugin.h" +#include "ksayit_ttsplugin.h" + + +FXPluginHandler::FXPluginHandler(QObject *parent, const char *name, KConfig *config) + : QObject(parent, name), m_config(config) +{ + m_mapPluginList.clear(); + m_lstActivePlugins.clear(); +} + + +FXPluginHandler::~FXPluginHandler() +{ + QMap<QString, fx_struct>::Iterator mit; + + for (mit=m_mapPluginList.begin(); mit!=m_mapPluginList.end(); ++mit){ + if ( (*mit).p != 0 ){ + delete (*mit).p; + } + } +} + + +void FXPluginHandler::searchPlugins() +{ + kdDebug(100200) << "FXPluginHandler::searchPlugins()" << endl; + + QStringList sRegistered; + fx_struct plugin; + + sRegistered.clear(); + m_mapPluginList.clear(); + + KTrader::OfferList offers = KTrader::self()->query("KSayIt/FXPlugin"); + KLibFactory *factory = NULL; + QString library = QString::null; + QString name = QString::null; + + KTrader::OfferList::Iterator it=offers.begin(); + for ( ;it!=offers.end(); ++it ){ + KService::Ptr ptr = (*it); + library = ptr->library(); + name = ptr->name(); + factory = KLibLoader::self()->factory( library.latin1() ); + if ( factory ){ + kdDebug(100200) << "FXPluginHandler::searchPlugins(): Plugin factory found." << endl; + // register found plugin + if ( !sRegistered.contains( QString(name) )){ + sRegistered.append( QString(name) ); + plugin.name = name; + plugin.library = library; + plugin.description = QString::null; + plugin.EffectID = 0; + plugin.p = NULL; + m_mapPluginList[plugin.name] = plugin; // update Plugin Map + kdDebug(100200) << "FXPluginHandler::searchPlugins(): " << plugin.name << " registered." << endl; + } + } + } +} + + +void FXPluginHandler::readConfiguration() +{ + kdDebug(100200) << "+++ entering FXPluginHandler::readConfiguration()" << endl; + + fx_struct plugin; + QMap<QString, fx_struct>::Iterator mit; + QStringList::Iterator lit; + + // unload all plugins and destroy the effect objects + lit = m_lstActivePlugins.begin(); + while ( lit != m_lstActivePlugins.end() ){ + mit = m_mapPluginList.find( *lit ); + if ( mit!=m_mapPluginList.end() ){ + plugin = *mit; + if ( (plugin.p != NULL) && (plugin.EffectID == 0) ){ + delete plugin.p; + plugin.p = NULL; + m_mapPluginList[plugin.name] = plugin; // update Plugin Map + lit = m_lstActivePlugins.remove( lit ); + } else { + lit++; + } + } + } + + // load active plugins as given in config file + m_config->setGroup("Effect Stack Configuration"); + QStringList conf_active = m_config->readListEntry("Activated"); + KLibFactory *factory = NULL; + + for (lit=conf_active.begin(); lit!=conf_active.end(); ++lit){ // for all in config + mit = m_mapPluginList.find(*lit); + if( mit!=m_mapPluginList.end() ){ + // plugin found in list of registered plugins + plugin = *mit; + // load plugin + factory = KLibLoader::self()->factory( (plugin.library).latin1() ); + if ( factory ){ + plugin.p = static_cast<FXPlugin*>( factory->create( (QObject*)this, (plugin.name).latin1() ) ); + if ( plugin.p ){ // Plugin found + plugin.p->setApplication( KApplication::kApplication() ); + plugin.description = plugin.p->getDescription_KS(); + // append to list of active plugins + m_lstActivePlugins.append( plugin.name ); + m_mapPluginList[plugin.name] = plugin; // update Plugin Map + kdDebug(100200) << "FXPluginHandler: FX-Plugin " << plugin.name << " active." << endl; + } + } + } + } +} + + +void FXPluginHandler::showEffectGUI(const QString &pname) +{ + kdDebug(100200) << "FXPluginHandler::showEffectGUI(): " << pname << endl; + + QMap<QString, fx_struct>::Iterator mit; + fx_struct plugin; + + // find plugin with name==pname in list and show its GUI + mit = m_mapPluginList.find(pname); + if ( mit != m_mapPluginList.end() ){ + plugin = *mit; + if ( plugin.p != NULL ){ // plugin loaded + plugin.p->showGUI_KS(); + return; + } else { + kdDebug(100200) << "Effect not active yet. Loading..." << endl; + KLibFactory *factory = KLibLoader::self()->factory( (plugin.library).latin1() ); + if ( factory ){ + plugin.p = static_cast<FXPlugin*>( factory->create( (QObject*)this, (plugin.name).latin1() ) ); + if ( plugin.p ){ // Plugin found + plugin.p->setApplication( KApplication::kApplication() ); + plugin.description = plugin.p->getDescription_KS(); + // append to list of active plugins + m_lstActivePlugins.append( plugin.name ); + m_mapPluginList[plugin.name] = plugin; // update Plugin Map + kdDebug(100200) << "FXPluginHandler: FX-Plugin " << plugin.name << " active." << endl; + plugin.p->showGUI_KS(); + return; + } + } + } + } + } + + +void FXPluginHandler::getPlugins(QStringList &pluginlist) +{ + // kdDebug(100200) << "FXPluginHandler::getPlugins" << endl; + + pluginlist.clear(); + QString sPname; + + QMap<QString, fx_struct>::Iterator mit; + for (mit=m_mapPluginList.begin(); mit!=m_mapPluginList.end(); ++mit){ + sPname = (*mit).name; //testing + pluginlist.append( sPname ); + } +} + + +void FXPluginHandler::activateEffect(const QString &pname, + KArtsServer *server, + StereoEffectStack *fx_stack) +{ + kdDebug(100200) << "FXPluginHandler::activateEffect: " << pname << endl; + + QMap<QString, fx_struct>::Iterator mit; + fx_struct plugin; + + // find plugin with name==pname + mit = m_mapPluginList.find(pname); + if ( mit!=m_mapPluginList.end() ){ + plugin = *mit; + if ( plugin.p != NULL ){ + plugin.EffectID = plugin.p->activate_KS(server, fx_stack); + m_mapPluginList[plugin.name] = plugin; // update Plugin Map + } else { + kdDebug(100200) << "Effect " << pname << " not found or inactive." << endl; + } + } +} + + +void FXPluginHandler::deactivateEffects(StereoEffectStack *fx_stack) +{ + kdDebug(100200) << "FXPluginHandler::deactivateEffects." << endl; + + QMap<QString, fx_struct>::Iterator mit; + fx_struct plugin; + + for (mit=m_mapPluginList.begin(); mit!=m_mapPluginList.end(); ++mit){ + if ( mit != m_mapPluginList.end() ){ + plugin = *mit; + if ( (plugin.EffectID != 0) && (plugin.p != NULL) ){ + // effect active and on stack + plugin.p->deactivate_KS(fx_stack, plugin.EffectID); + kdDebug(100200) << plugin.name << " with Effect ID " << plugin.EffectID << " removed." << endl; + plugin.EffectID = 0; + m_mapPluginList[plugin.name] = plugin; // update Plugin Map + } + } + } +} + + + + + +#include "fxpluginhandler.moc" diff --git a/ksayit/src/fxpluginhandler.h b/ksayit/src/fxpluginhandler.h new file mode 100644 index 0000000..1a3d54a --- /dev/null +++ b/ksayit/src/fxpluginhandler.h @@ -0,0 +1,99 @@ +// +// C++ Interface: fxpluginhandler +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef FXPLUGINHANDLER_H +#define FXPLUGINHANDLER_H + +// QT includes +#include <qobject.h> +#include <qlibrary.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qmap.h> +// #include <qvaluelist.h> + +// KDE includes +#include <kconfig.h> +#include <arts/kartsserver.h> +#include <arts/artsflow.h> + +using namespace Arts; + +// App specific includes +#include "ksayit_fxplugin.h" + +/** +@author Robert Vogl +*/ +/** Internal structure of the effect plugin + */ +typedef struct { + QString name; // KService::Ptr->name() + QString library; // KService::Ptr->library() + QString description; + long EffectID; // !=0, if effect is on the effect stack. + FXPlugin *p; // factory->create(...) +} fx_struct; + + +class FXPluginHandler : public QObject +{ +Q_OBJECT +public: + FXPluginHandler(QObject *parent = 0, const char *name = 0, KConfig *config=0); + ~FXPluginHandler(); + +public: // Methods + /** Loads the activated plugins. + */ + void readConfiguration(); + + /** Loads any available plugin from the directories containing KSayIt plugins, + * fills the plugin_struct with the corresponding data and unloads the plugin. + */ + void searchPlugins(); + + /** Shows the GUI to setup the effect named name + \param pname The name of the effect to configure. + */ + void showEffectGUI(const QString &pname); + + /** Activates the named effect + \param pname Name of the effect to activate. + \param server A pointer to the soundserver instance. + \param fx_stack A pointer to the effect stack of the soundserver. + */ + void activateEffect(const QString &pname, + KArtsServer *server, + StereoEffectStack *fx_stack); + + /** Removes all effects from the soundservers effect stack. + \param fx_stack A pointer to the effect stack of the soundserver. + */ + void deactivateEffects(StereoEffectStack *fx_stack); + + /** Returns a list of all available plugins. + \param pluginlist A reference to a QStringList that contains the available plugins. + */ + void getPlugins(QStringList &pluginlist); + +private: // Attributes + KConfig *m_config; + QMap<QString, fx_struct> m_mapPluginList; // holds all plugins found on the system + // QMap<QString, fx_struct> m_mapActivePlugins; // holds the active effects + QStringList m_lstActivePlugins; + + +}; + + + +#endif diff --git a/ksayit/src/fxsetupimpl.cpp b/ksayit/src/fxsetupimpl.cpp new file mode 100644 index 0000000..cb85080 --- /dev/null +++ b/ksayit/src/fxsetupimpl.cpp @@ -0,0 +1,159 @@ +/*************************************************************************** + fxsetupimpl.cpp - description + ------------------- + begin : Mo Nov 24 2003 + copyright : (C) 2003 by voglrobe + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +// QT includes +#include <qstringlist.h> +#include <qpushbutton.h> + +// KDE includes +#include <kdebug.h> + +// App specific inlcudes +#include "fxsetupimpl.h" +// #include "freeverbsetupimpl.h" +#include "fxpluginhandler.h" + +FX_SetupImpl::FX_SetupImpl(QWidget *parent, const char *name, + KConfig *config, + FXPluginHandler *fxpluginhandler ) + : FX_Setup(parent,name), m_config(config), m_fxpluginhandler(fxpluginhandler) +{ + m_fxpluginhandler->getPlugins(pluginlist); + + Init(pluginlist); +} + + +FX_SetupImpl::~FX_SetupImpl() +{ +} + +void FX_SetupImpl::slotAdd() +{ + // move effect from Available-List to Active-List + int index = listBox_Available->currentItem(); + if ( index == -1 ) + return; + listBox_Active ->insertItem( listBox_Available->text(index), -1 ); + listBox_Available->removeItem( index ); + pushButton_removeAll->setEnabled(true); +} + + +void FX_SetupImpl::slotRemove() +{ + // move effect from Active-List to Available-List + int index = listBox_Active->currentItem(); + if ( index == -1 ) + return; + listBox_Available->insertItem( listBox_Active->text(index), -1 ); + listBox_Active ->removeItem( index ); + + if (listBox_Active->count() == 0) + pushButton_removeAll->setEnabled(false); +} + + +void FX_SetupImpl::slotRemoveAll() +{ + kdDebug() << "FX_SetupImpl::slotRemoveAll()" << endl; + + // move all from Active-List to Available-List + for(uint i=0; i<listBox_Active->count(); i++){ + listBox_Available->insertItem( listBox_Active->text((int)i) ); + } + listBox_Active->clear(); + pushButton_removeAll->setEnabled(false); +} + + +void FX_SetupImpl::slotReload() +{ + kdDebug() << "FX_SetupImpl::slotReload()" << endl; + + Init(pluginlist); +} + + +void FX_SetupImpl::slotConfigureEffect(QListBoxItem *item) +{ + m_fxpluginhandler->showEffectGUI(item->text()); +} + + +void FX_SetupImpl::Init(QStringList c_avail) +{ + m_config->setGroup("Effect Stack Configuration"); + QStringList conf_active = m_config->readListEntry("Activated"); + QStringList c_active; + QStringList::Iterator sit, it; + + listBox_Available->clear(); + listBox_Active->clear(); + c_active.clear(); + + pushButton_removeAll->setEnabled(false); + + for (sit=conf_active.begin(); sit!=conf_active.end(); ++sit){ + it = c_avail.find(*sit); + if ( it!=c_avail.end() ){ // active plugin as per config-file in pluginlist found + c_active.append(*sit); // append to active list + c_avail.remove(*sit); // remove active plugin from the list of avail plugins + } + } + + if ( !c_active.isEmpty() ){ + pushButton_removeAll->setEnabled(true); + } + + // Fill ListBoxes + for(it=c_avail.begin(); it!=c_avail.end(); ++it){ + listBox_Available->insertItem( (*it), -1 ); + } + for(it=c_active.begin(); it!=c_active.end(); ++it){ + listBox_Active->insertItem( (*it), -1 ); + } +} + + +void FX_SetupImpl::slotSaveWasClicked() +{ + m_config->setGroup("Effect Stack Configuration"); + + // Read ListBox Available FX + QStringList slist; + for(uint i=0; i<listBox_Available->count(); i++){ + slist.append( listBox_Available->text( (int)i) ); + } + // Write StringList + m_config->writeEntry("Available", slist); + + // Read ListBox Activated FX + slist.clear(); + QString t; + for(uint i=0; i<listBox_Active->count(); i++){ + t = listBox_Active->text( (int)i ); + slist.append( t ); + } + // Write StringList + m_config->writeEntry("Activated", slist); + m_config->sync(); + slist.clear(); +} + + +#include "fxsetupimpl.moc" diff --git a/ksayit/src/fxsetupimpl.h b/ksayit/src/fxsetupimpl.h new file mode 100644 index 0000000..403631d --- /dev/null +++ b/ksayit/src/fxsetupimpl.h @@ -0,0 +1,90 @@ +/*************************************************************************** + fxsetupimpl.h - description + ------------------- + begin : Mo Nov 24 2003 + copyright : (C) 2003 by voglrobe + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef FXSETUPIMPL_H +#define FXSETUPIMPL_H + +// QT includes +#include <qwidget.h> +#include <qlistbox.h> + + +// KDE includes +#include <kconfig.h> + +// App specific includes +#include "fx_setup.h" + +// forward declaration +class FXPluginHandler; + +/** + *@author voglrobe + */ +class FX_SetupImpl : public FX_Setup { + Q_OBJECT + +public: + FX_SetupImpl(QWidget *parent=0, const char *name=0, + KConfig *config=0, + FXPluginHandler *fxpluginhandler=0); + ~FX_SetupImpl(); + +public slots: + /** Adds an effect to the list of active effects. + */ + void slotAdd(); + + /** Removes an effect from the list of active effects. + */ + void slotRemove(); + + /** Removes all effects from the list of active effects. + */ + void slotRemoveAll(); + + /** Recovers last saved state. + */ + void slotReload(); + + /** Called by a double click on an effect in the list of active effects. + Opens a modal dialog to configure the efffect. + \param item The double clicked item. + */ + void slotConfigureEffect(QListBoxItem *item); + + /** Saves the configuration + */ + void slotSaveWasClicked(); + +private: // Methods + /** Loads the configuration and initializes the widget. + \param c_avail List of available plugins. + */ + void Init(QStringList c_avail); + +private: + KConfig *m_config; + FXPluginHandler *m_fxpluginhandler; + QStringList pluginlist; + +}; + + + +#endif + diff --git a/ksayit/src/hi16-app-ksayit.png b/ksayit/src/hi16-app-ksayit.png Binary files differnew file mode 100644 index 0000000..fcd7183 --- /dev/null +++ b/ksayit/src/hi16-app-ksayit.png diff --git a/ksayit/src/hi32-app-ksayit.png b/ksayit/src/hi32-app-ksayit.png Binary files differnew file mode 100644 index 0000000..8bee3ef --- /dev/null +++ b/ksayit/src/hi32-app-ksayit.png diff --git a/ksayit/src/hi32-app-ksayit_clipempty.png b/ksayit/src/hi32-app-ksayit_clipempty.png Binary files differnew file mode 100644 index 0000000..6992a16 --- /dev/null +++ b/ksayit/src/hi32-app-ksayit_clipempty.png diff --git a/ksayit/src/hi32-app-ksayit_talking.png b/ksayit/src/hi32-app-ksayit_talking.png Binary files differnew file mode 100644 index 0000000..44717e6 --- /dev/null +++ b/ksayit/src/hi32-app-ksayit_talking.png diff --git a/ksayit/src/ksayit.cpp b/ksayit/src/ksayit.cpp new file mode 100644 index 0000000..131db8c --- /dev/null +++ b/ksayit/src/ksayit.cpp @@ -0,0 +1,908 @@ +/*************************************************************************** + ksayit.cpp - description + ------------------- + begin : Son Aug 10 13:26:57 EDT 2003 + copyright : (C) 2003 by Robert Vogl + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ +#include <stdlib.h> // getenv, system + +// include files for QT +#include <qdir.h> +#include <qapplication.h> +#include <qdockwindow.h> +#include <qfileinfo.h> +#include <qfile.h> + +// include files for KDE +#include <klocale.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kdialogbase.h> +#include <kfiledialog.h> +#include <kmenubar.h> +#include <kpopupmenu.h> +#include <kstatusbar.h> +#include <kconfig.h> +#include <kstdaction.h> +#include <kedittoolbar.h> +#include <kkeydialog.h> +#include <kurl.h> +#include <kstandarddirs.h> + +// application specific includes +#include "ksayit.h" +#include "ksayitviewimpl.h" +#include "voicesetupdlg.h" +#include "ksayitsystemtray.h" +#include "effectstack.h" +#include "fxpluginhandler.h" +#include "kttsdlib.h" +#include "doctreeviewimpl.h" +#include "ksayitbookmarkhandler.h" + +// #define KSAYITUI "/home/voglrobe/Projekte/ksayit/ksayit/ksayitui.rc" +#define KSAYITUI "ksayitui.rc" +#define ID_STATUS_MSG 1 + +KSayItApp::KSayItApp(QWidget* parent, const char* name, WFlags f, + const QCString &objID) + : KMainWindow(parent, name, f), DCOPObject(objID) +{ + config = NULL; + view = NULL; + tray = NULL; + es = NULL; + treeview = NULL; + bkManager = NULL; + bkHandler = NULL; + bkMenu = NULL; + m_currentBookmarkFile = QString::null; + + config=kapp->config(); + m_kttslib = new KTTSDLib(this, "KTTSD-Library", kapp); + + initView(); + initStatusBar(); + initActions(); + initBookmarkManager( i18n("Untitled") ); + + createGUI(KSAYITUI); + setAutoSaveSettings("MainWindow"); + + readOptions(); + + // connect TTS plugin handler to this object + connect(m_kttslib, SIGNAL(signalFinished()), + this, SLOT(slotTTSFinished()) ); + + // only used if library thinks it has to call the preferences dialog. + // e.g. when it detects a bad configuration. + connect(m_kttslib, SIGNAL(signalCallPreferences()), + this, SLOT(slotPreferences()) ); + + // init Clipboard + cb = QApplication::clipboard(); + connect(cb, SIGNAL(dataChanged()), this, SLOT(slotClipboardChanged()) ); + + // create SystemTray object + tray = new KSayItSystemTray(this, "system_tray"); + connect(tray, SIGNAL(signalCallPreferences()), this, SLOT(slotPreferences()) ); + connect(tray, SIGNAL(signalSayActivated()), this, SLOT(slotSayText()) ); + connect(tray, SIGNAL(signalSayClipboard()), this, SLOT(slotSayClipboard()) ); + connect(tray, SIGNAL(signalShutUpActivated()), this, SLOT(slotStopActivated()) ); + connect(tray, SIGNAL(signalPauseActivated()), this, SLOT(slotPauseActivated()) ); + connect(tray, SIGNAL(signalNextActivated()), this, SLOT(slotNextSentenceActivated()) ); + connect(tray, SIGNAL(signalPrevActivated()), this, SLOT(slotPrevSentenceActivated()) ); + tray->show(); + tray->setEnabled(true); + + // create the FX plugin handler + m_fxpluginhandler = new FXPluginHandler(this, "fxpluginhandler", config); + m_fxpluginhandler->searchPlugins(); + + // create object for effectstack + es = new EffectStack(m_fxpluginhandler, config); + + // emit signalConfigChanged(); + m_kttslib->reloadConfiguration(); + m_fxpluginhandler ->readConfiguration(); + + // init docview + // treeview->clear(); + // treeview->createEmptyDocument(); + slotClear(); +} + +KSayItApp::~KSayItApp() +{ + // delete kapp->mainWidget(); + delete m_kttslib; + delete tray; + delete m_fxpluginhandler; + delete es; + delete view; + if (bkHandler) + delete bkHandler; + if (bkMenu) + delete bkMenu; +} + +void KSayItApp::initActions() +{ + // Standard-Actions + open = KStdAction::open(this, SLOT(slotFileOpen()), actionCollection()); + save = KStdAction::save(this, SLOT(slotFileSave()), actionCollection()); + saveAs = KStdAction::saveAs(this, SLOT(slotFileSaveAs()), actionCollection()); + KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection()); + KStdAction::close(this, SLOT(slotCloseMainWindow()), actionCollection()); + cut = KStdAction::cut(view, SLOT(slotCut()), actionCollection()); + copy = KStdAction::copy(view, SLOT(slotCopy()), actionCollection()); + paste = KStdAction::paste(view, SLOT(slotPaste()), actionCollection()); + preferences = KStdAction::preferences(this, SLOT(slotPreferences()), actionCollection()); + KStdAction::keyBindings(this, SLOT(slotEditKeys()), actionCollection()); + KStdAction::configureToolbars(this, SLOT(slotConfigureToolbar()), actionCollection()); + KStdAction::showToolbar("mainToolBar", actionCollection()); + statusBarAction = KStdAction::showStatusbar(this, SLOT(slotToggleStatusBar()), actionCollection()); + + // User defined actions + say = new KAction (i18n("Say"), + Qt::Key_F9, + this, SLOT (slotSayText()), + actionCollection(), + "say_it"); + + pause = new KAction (i18n("Pause"), + Qt::Key_Pause, + this, SLOT (slotPauseActivated()), + actionCollection(), + "pause"); + + shutup = new KAction (i18n("Shut Up"), + Qt::Key_F10, + this, SLOT (slotStopActivated()), + actionCollection(), + "shut_up"); + + next_sentence = new KAction (i18n("Next Sentence"), + Qt::Key_Next, + this, SLOT (slotNextSentenceActivated()), + actionCollection(), + "next_sentence"); + + + prev_sentence = new KAction (i18n("Previous Sentence"), + Qt::Key_Prior, + this, SLOT(slotPrevSentenceActivated()), + actionCollection(), + "prev_sentence"); + + clear = new KAction (i18n("Clear"), + Qt::Key_F12, + this, SLOT(slotClear()), + actionCollection(), + "clear"); + + edit = new KToggleAction( i18n("Edit Text"), + 0, + this, SLOT(slotEditToggled()), + actionCollection(), + "edittext"); + + bookmarkmenu = new KActionMenu( i18n("Bookmarks"), + "bookmark", // icon + actionCollection(), + "bookmarks"); // name + bookmarkmenu->setDelayed(false); + + // default disable/enable + save ->setEnabled(false); + saveAs ->setEnabled(false); + copy ->setEnabled(false); + cut ->setEnabled(false); + paste ->setEnabled(false); + say ->setEnabled(false); + pause ->setEnabled(false); + shutup ->setEnabled(false); + next_sentence->setEnabled(false); + prev_sentence->setEnabled(false); + preferences ->setEnabled(true); + edit ->setChecked(false); + bookmarkmenu ->setEnabled(false); + m_ap_saying = false; + m_ap_paused = false; + m_textview_empty = true; +} + + +void KSayItApp::initBookmarkManager(const QString &filename) +{ + QString bkFile = getBookmarkDir( filename ); + if ( bkFile.isNull() ) + return; + + m_currentBookmarkFile = bkFile; + bkManager = KBookmarkManager::managerForFile( bkFile, false ); + + // create BookmarkHandler object + if ( bkHandler ) + delete bkHandler; + bkHandler = new KSayItBookmarkHandler(bkManager, this); + + // create Bookmarkmenu + KPopupMenu *bkPopupMenu = bookmarkmenu->popupMenu(); + if ( bkMenu ) + delete bkMenu; + bkMenu = new KBookmarkMenu(bkManager, bkHandler, bkPopupMenu, 0, true ); +} + + +void KSayItApp::slotNotifyBookmarkHandler(const QString &ID, const QString &title) +{ + if ( bkHandler ) + bkHandler->notifyBookmarkHandler(ID, title); +} + + +void KSayItApp::slotDeleteBookmark(const QString &url, const QString &title) +{ + kdDebug(100200) << "KSayItApp::slotDeleteBookmark(" << url << ")" << endl; + if ( bkHandler ) + bkHandler->deleteBookmark( url, title ); +} + + +QString KSayItApp::getBookmarkDir(const QString &filename) +{ + QString bkRelPath = "ksayit/ksayit_bookmarks/" + filename + ".bookmarks"; + QString bkFile; + bkFile = locateLocal("data", bkRelPath); + return bkFile; +} + + +void KSayItApp::slotSetBookmarkFilename(const QString &newname) +{ + kdDebug(100200) << "KSayItApp::slotSetBookmarkFilename(" << newname << ")" << endl; + + initBookmarkManager(newname); +} + + +void KSayItApp::slotChangeBookmarkFilename(const QString &newname) +{ + kdDebug(100200) << "KSayItApp::slotChangeBookmarkFilename(" << newname << ")" << endl; + + if ( m_currentBookmarkFile.isNull() ) + return; + + QString newbkFile = getBookmarkDir(newname); + if ( newbkFile.isNull() ) + return; + + // copy old bookmarkfile to new file + if ( m_currentBookmarkFile != newbkFile ){ + if ( QFile::exists(m_currentBookmarkFile) ){ + QString command = QString("cp %1 %2").arg(m_currentBookmarkFile).arg(newbkFile); + system( command.ascii() ); + } + // install new BookmarkHandler based on the new file + initBookmarkManager(newname); + } +} + + +QString KSayItApp::setItemByBookmark( const QString &ID, const QString &title ) +{ + QString result; + result = treeview->selectItemByID( ID, title ); + return result; +} + + +void KSayItApp::initStatusBar() +{ + // STATUSBAR + statusBar()->insertItem(i18n("Ready."), ID_STATUS_MSG, 1); + statusBar()->setItemAlignment(ID_STATUS_MSG, Qt::AlignLeft); +} + + +void KSayItApp::initView() +{ + // create the main widget + view = new KSayItViewImpl(this); + view->setMinimumSize(view->sizeHint()); + setCentralWidget(view); + // connections + connect( view, SIGNAL(signalEnableCopyCut(bool)), + this, SLOT(slotEnableCopyCut(bool))); + connect( view, SIGNAL(signalShowStatus(const QString &)), + this, SLOT(slotStatusMsg(const QString &))); + connect( view, SIGNAL(signalSetCaption(const QString &)), + this, SLOT(slotSetCaption(const QString &))); + connect( view, SIGNAL(signalTextChanged(bool)), + this, SLOT(slotTextChanged(bool)) ); + + // DockWindow + QDockWindow *docview = new QDockWindow(QDockWindow::InDock, this, "docview"); + treeview = new DocTreeViewImpl(docview, "treeview"); + treeview->enableContextMenus( true ); + // treeview->clear(); + docview->setWidget(treeview); + docview->setResizeEnabled(true); + this->setDockEnabled(docview, Qt::DockTop, false); + this->setDockEnabled(docview, Qt::DockBottom, false); + this->moveDockWindow(docview, Qt::DockLeft); + connect( treeview, SIGNAL(signalContentChanged(const QString&)), + this, SLOT(slotTreeViewChanged(const QString&)) ); + connect( treeview, SIGNAL(signalSetText(const QString&)), + this, SLOT(slotSetText(const QString&)) ); + connect( treeview, SIGNAL(signalAllNodesProcessed()), + this, SLOT(slotSayNode()) ); + connect( treeview, SIGNAL(signalEnableTextedit(bool)), + this, SLOT(slotEnableTextedit(bool)) ); + connect( treeview, SIGNAL(signalNotifyBookmarkManager(const QString&, const QString&)), + this, SLOT(slotNotifyBookmarkHandler(const QString&, const QString&)) ); + connect( treeview, SIGNAL(signalSetBookmarkFilename(const QString&)), + this, SLOT(slotSetBookmarkFilename(const QString&)) ); + connect( treeview, SIGNAL(signalChangeBookmarkFilename(const QString&)), + this, SLOT(slotChangeBookmarkFilename(const QString&)) ); + connect( treeview, SIGNAL(signalDeleteBookmark(const QString&, const QString&)), + this, SLOT(slotDeleteBookmark(const QString&, const QString&)) ); +} + + +void KSayItApp::readOptions() +{ + applyMainWindowSettings( config, "MainWindow" ); + statusBarAction->setChecked(!statusBar()->isHidden()); +} + +void KSayItApp::closeEvent(QCloseEvent *ce) +{ + ce->ignore(); + if ( !this->isVisible() ){ + slotFileQuit(); + } else { + this->hide(); + } +} + + +///////////////////////////////////////////////////////////////////// +// DCOP FUNCTIONS +///////////////////////////////////////////////////////////////////// + +ASYNC KSayItApp::dcopSayText(QString msg) +{ + slotSetText( msg ); + sayActivated(); +} + +ASYNC KSayItApp::dcopStop() +{ + slotStopActivated(); +} + + +ASYNC KSayItApp::dcopSayXmlFile(KURL url) +{ + slotStatusMsg(i18n("Say XML file...")); + m_enableChangeNotifications = false; + + try{ + if ( !url.isEmpty() ){ + resetView(); + treeview->openFile( url ); + setActions(ACTIONS::PLAY | ACTIONS::FFWD); + save ->setEnabled(false); + saveAs->setEnabled(true); + edit->setChecked(false); + treeview->setEditMode( false ); + } + } + catch( QString err ){ + KMessageBox::error(this, err); + save ->setEnabled(false); + saveAs->setEnabled(true); + } + + m_enableChangeNotifications = true; + + slotSayText(); +} + + +///////////////////////////////////////////////////////////////////// +// SLOT IMPLEMENTATION +///////////////////////////////////////////////////////////////////// + +void KSayItApp::slotEditToggled() +{ + if ( edit->isChecked() ){ + treeview->setEditMode( true ); + slotStatusMsg(i18n("Edit Mode ON.")); + } else { + treeview->setEditMode( false ); + slotStatusMsg(i18n("Edit Mode OFF.")); + } +} + + +void KSayItApp::slotSaveOptions() +{ + saveMainWindowSettings( config, "MainWindow" ); + config->sync(); +} + + +void KSayItApp::slotConfigureToolbar() +{ + saveMainWindowSettings( config, "MainWindow" ); + KEditToolbar dlg(actionCollection(), KSAYITUI); + connect(&dlg,SIGNAL(newToolbarConfig()),this,SLOT(slotNewToolbarConfig())); + if (dlg.exec()) + { + createGUI(KSAYITUI); + } +} + + +void KSayItApp::slotNewToolbarConfig() +{ + applyMainWindowSettings( config, "MainWindow" ); +} + + +void KSayItApp::slotFileOpen() +{ + slotStatusMsg(i18n("Open file...")); + m_enableChangeNotifications = false; + + // open filerequester + QString fn; + QString usershome( getenv("HOME") ); + KURL url = KFileDialog::getOpenURL(usershome, QString::null, this, i18n("File to Speak") ); + try{ + if ( !url.isEmpty() ){ + resetView(); + treeview->openFile( url ); + setActions(ACTIONS::PLAY | ACTIONS::FFWD); + save ->setEnabled(false); + saveAs->setEnabled(true); + edit->setChecked(false); + treeview->setEditMode( false ); + bookmarkmenu->setEnabled(true); + } + } + catch( QString err ){ + KMessageBox::error(this, err); + save ->setEnabled(false); + saveAs->setEnabled(true); + bookmarkmenu->setEnabled(false); + } + + m_enableChangeNotifications = true; +} + + +void KSayItApp::slotFileSave() +{ + slotStatusMsg(i18n("Save file...")); + try { + treeview->saveFile(); + save ->setEnabled(false); + saveAs->setEnabled(true); + } + catch ( QString err ) + { + KMessageBox::error(this, err); + save ->setEnabled(false); + saveAs->setEnabled(true); + } +} + + +void KSayItApp::slotFileSaveAs() +{ + slotStatusMsg(i18n("Save file as...")); + try { + treeview->saveFileAs(); + save ->setEnabled(true); + saveAs->setEnabled(true); + bookmarkmenu->setEnabled(true); + } + catch ( QString err ) + { + KMessageBox::error(this, err); + save ->setEnabled(true); + saveAs->setEnabled(true); + bookmarkmenu->setEnabled(false); + } +} + + +void KSayItApp::slotEnableCopyCut(bool enable) +{ + copy->setEnabled(enable); + cut ->setEnabled(enable); +} + + +void KSayItApp::slotEditKeys() +{ + KKeyDialog::configure( actionCollection() ); //, xmlFile()); +} + + +void KSayItApp::slotFileQuit() +{ + slotStatusMsg(i18n("Exiting...")); + int really = KMessageBox::questionYesNo( this, i18n("Do you really want to quit?"), QString::null, KStdGuiItem::quit(), KStdGuiItem::cancel() ); + if (really == KMessageBox::Yes){ + slotSaveOptions(); + kapp->quit(); + } else { + slotStatusMsg(i18n("Ready.")); + } +} + + +void KSayItApp::slotCloseMainWindow() +{ + this->hide(); +} + + +void KSayItApp::slotToggleStatusBar() +{ + slotStatusMsg(i18n("Toggle the statusbar...")); + //turn Statusbar on or off + if(statusBar()->isVisible()) + statusBar()->hide(); + else + statusBar()->show(); + + slotStatusMsg(i18n("Ready.")); +} + + +void KSayItApp::slotStatusMsg(const QString &text) +{ + // change status message permanently + statusBar()->clear(); + statusBar()->changeItem(text, ID_STATUS_MSG); +} + + +void KSayItApp::slotSetCaption(const QString &caption) +{ + this->setCaption(caption); +} + + +void KSayItApp::slotPreferences() +{ + // create Preferences object and open it + VoiceSetupDlg *prefs = new VoiceSetupDlg(this, "preferences", i18n("Setup"), true, + config, + m_fxpluginhandler, + m_kttslib); + + if (prefs->exec() == QDialog::Accepted){ + delete prefs; + m_kttslib->reloadConfiguration(); + m_fxpluginhandler ->readConfiguration(); + } else { + delete prefs; + } +} + + +void KSayItApp::slotClipboardChanged() +{ + if ( cb->text().isEmpty() ){ + tray->changeState( StateCLIPEMPTY::Instance() ); + paste->setEnabled(false); + return; + } + + if ( cb->data(QClipboard::Clipboard)->provides("text/plain") ){ + tray->changeState( StateWAIT::Instance() ); + paste->setEnabled(true); + } else { + tray->changeState( StateCLIPEMPTY::Instance() ); + paste->setEnabled(false); + } +} + + +void KSayItApp::slotTextChanged(bool empty) +{ + m_textview_empty = empty; + + // do nothing if change notifications from the Textedit are + // currently not welcome. + if ( !m_enableChangeNotifications ) + return; + + // do nothing if say is in progress + if ( m_ap_saying ) + return; + + kdDebug(100200) << "KSayItApp::slotTextChanged( " << empty << " )" << endl; + + // Update actions + if ( empty ){ + setActions(0); + } else { + setActions(ACTIONS::PLAY); + } + // save ->setEnabled(!empty); + saveAs->setEnabled(!empty); + + // update TreeView-Item + treeview->setNodeContent( view->getText() ); + +} + + +void KSayItApp::slotClear() +{ + m_enableChangeNotifications = false; + // TextEdit clear + view->textClear(); + + // TreeView clear + treeview->clear(); + treeview->createEmptyDocument(); + treeview->setEditMode( true ); + edit->setChecked(true); + slotStatusMsg(i18n("Edit Mode ON.")); + + // set actions + save ->setEnabled(false); + saveAs->setEnabled(false); + setActions(0); + bookmarkmenu->setEnabled(false); + m_enableChangeNotifications = true; +} + + +void KSayItApp::slotSayClipboard() +{ + // get Text from clipboard + slotStatusMsg(i18n("speaking Clipboard...")); + setActions(ACTIONS::PAUSE | ACTIONS::STOP | ACTIONS::FFWD | ACTIONS::FREV); + tray->changeState( StateSAY::Instance() ); + + clip = cb->text(); + // sayActivated( clip.stripWhiteSpace() ); + // set text and say it + slotSetText( clip.stripWhiteSpace() ); + sayActivated(); +} + + +void KSayItApp::slotSayText() +{ + // say Text from text-window + setActions(ACTIONS::PAUSE | ACTIONS::STOP | ACTIONS::FFWD | ACTIONS::FREV); + tray->changeState( StateSAY::Instance() ); + + slotStatusMsg(i18n("synthesizing...")); + + if ( m_ap_paused ){ + m_ap_paused = false; + m_kttslib->resume(); + } else { + es->loadEffects(); + treeview->sayActiveNodeAndChilds(); + } +} + + +void KSayItApp::slotSayNode() +{ + sayActivated(); +} + + +void KSayItApp::slotSetText(const QString &text) +{ + // also invoked by the treeview for the each node + if ( text.isNull() ) + return; + + // put text on the stack of KTTS + m_kttslib->setText( text ); +} + +void KSayItApp::sayActivated() +{ + kdDebug(100200) << "KSayItApp::sayActivated()" << endl; + + preferences->setEnabled(false); + m_ap_saying = true; + + try { + m_kttslib->sayText(); + } + catch (QString err){ + kdDebug(100200) << "Exception catched in KSayItApp::sayActivated()" << endl; + KMessageBox::sorry(0, err, i18n("Unable to speak text")); + slotFinished(); + } +} + + +void KSayItApp::slotTTSFinished() +{ + kdDebug(100200) << "KSayItApp::slotTTSFinished()" << endl; + es->unloadEffects(); + slotFinished(); +} + + +void KSayItApp::slotFinished() +{ + kdDebug(100200) << "KSayItApp::slotFinished()" << endl; + + // disable/enable actions + m_ap_paused = false; + + if ( m_textview_empty ){ + setActions(0); + } else { + setActions(ACTIONS::PLAY); + } + tray->changeState( StateWAIT::Instance() ); + preferences->setEnabled(true); + m_ap_saying = false; + slotStatusMsg(i18n("Ready.")); +} + + +void KSayItApp::slotStopActivated() +{ + m_kttslib->stop(); + // slotFinished(); +} + + +void KSayItApp::slotPauseActivated() +{ + kdDebug(100200) << "KSayItApp::slotPauseActivated()" << endl; + + m_kttslib->pause(); + m_ap_paused = true; + setActions(ACTIONS::PLAY | ACTIONS::STOP); + tray->changeState( StateSAY::Instance() ); + slotStatusMsg(i18n("Paused...")); +} + + +void KSayItApp::slotNextSentenceActivated() +{ + kdDebug(100200) << "KSayItApp::slotNextSentenceActivated()" << endl; + m_kttslib->ffwd(); +} + + +void KSayItApp::slotPrevSentenceActivated() +{ + kdDebug(100200) << "KSayItApp::slotPrevSentenceActivated()" << endl; + m_kttslib->frev(); +} + + +void KSayItApp::setActions(int actions) +{ + // ACTIONS::PLAY | ACTIONS::STOP | ACTIONS::PAUSE | ACTIONS::FFWD | ACTIONS::FREV; + + // Get the mask of supported actions from the plugin. + int mask = m_kttslib->getActions(); + kdDebug(100200) << QString("KSayItApp:PSA: %1").arg(mask, 0, 2) << endl; + + // disable actions not supported by the plugin + int ma = actions & mask; + + if (ma & ACTIONS::PLAY){ + say->setEnabled(true); + } else { + say->setEnabled(false); + } + if (ma & ACTIONS::STOP){ + shutup->setEnabled(true); + } else { + shutup->setEnabled(false); + } + if (ma & ACTIONS::PAUSE){ + pause->setEnabled(true); + } else { + pause->setEnabled(false); + } + if (ma & ACTIONS::FFWD){ + next_sentence->setEnabled(true); + } else { + next_sentence->setEnabled(false); + } + if (ma & ACTIONS::FREV){ + prev_sentence->setEnabled(true); + } else { + prev_sentence->setEnabled(false); + } + + tray->setActions( say->isEnabled(), pause->isEnabled(), shutup->isEnabled(), + next_sentence->isEnabled(), prev_sentence->isEnabled() ); +} + + +void KSayItApp::slotTreeViewChanged(const QString &str) +{ + kdDebug(100200) << "KSayItApp::slotTreeViewChanged()" << endl; + + if ( !m_ap_saying ) + setActions(ACTIONS::PLAY); + + m_enableChangeNotifications = false; + view->textClear(); + view->setText(str); + m_enableChangeNotifications = true; +} + + +void KSayItApp::slotEnableTextedit(bool enable) +{ + kdDebug(100200) << "KSayItApp::slotEnableTextedit( " << enable << " )" << endl; + + view->enableTextedit( enable ); +} + + +void KSayItApp::resetView() +{ + m_enableChangeNotifications = false; + // TextEdit clear + view->textClear(); + + // TreeView clear + treeview->clear(); + + // set actions + save ->setEnabled(false); + saveAs->setEnabled(false); + setActions(0); + m_enableChangeNotifications = true; +} + + +void KSayItApp::slotAddBookmark() +{ + kdDebug(100200) << "KSayItApp::slotAddBookmark()" << endl; + + +} + + +void KSayItApp::slotEditBookmarks() +{ + kdDebug(100200) << "KSayItApp::slotEditBookmark()" << endl; + + +} + + + +#include "ksayit.moc" diff --git a/ksayit/src/ksayit.desktop b/ksayit/src/ksayit.desktop new file mode 100644 index 0000000..424b09e --- /dev/null +++ b/ksayit/src/ksayit.desktop @@ -0,0 +1,64 @@ +[Desktop Entry] +Type=Application +Exec=ksayit -caption "%c" %i +Icon=ksayit +DocPath=ksayit/index.html +Terminal=false +Name=KSayIt +Name[hi]=के-से-इट +Name[mk]=KSaylt +Name[ne]=के से इट +Name[sk]=PovedzTo +Name[sv]=Ksayit +Name[tg]=KSayIt +Name[tr]=Ksayit +Name[vi]=Nói K +GenericName=Text-to-Speech Frontend +GenericName[bg]=Синтез на глас +GenericName[bs]=Program za izgovaranje teksta +GenericName[ca]=Frontal per text a veu +GenericName[cs]=Rozhraní hlasové syntézy +GenericName[da]=Forende for tekst-til-tale +GenericName[de]=Oberfläche für die Sprachausgabe +GenericName[el]=Μετατροπή κειμένου σε ομιλία +GenericName[es]=Interfaz de administración del sistema de texto a voz de KDE +GenericName[et]=Teksti kõneks muutmine +GenericName[eu]=Testutik hizketarako interfazea +GenericName[fa]=پایانۀ متن به گفتار +GenericName[fi]=Teksti puheeksi käyttöliittymä +GenericName[fr]=Interface pour la synthèse vocale +GenericName[ga]=Comhéadan Téacs-go-Caint +GenericName[gl]=Interface de Texto-para-Fala +GenericName[hu]=Szövegfelolvasó +GenericName[is]=Texti-í-tal myndrænt viðmót +GenericName[it]=Interfaccia di pronuncia +GenericName[ja]=テキスト読み上げフロントエンド +GenericName[ka]=ტექსტი-გახმოვანების ინტერფეისი +GenericName[km]=ផ្នែកខាងមុខអត្ថបទដែលត្រូវនិយាយ +GenericName[lt]=Teksto vertimo kalba naudotojo sąsaja +GenericName[mk]=Преден дел за текст-во-говор +GenericName[ms]=Antaramuka Teks-ke-Tutur +GenericName[mt]=Programm għal Test-għal-Vuċi +GenericName[nb]=Brukerflate for tekst til tale +GenericName[nds]=Böversiet för den Vörleser +GenericName[ne]=पाठ वाचक फ्रन्टइन्ड +GenericName[nl]=Tekst-tot-spraak-schil +GenericName[pa]=ਪਾਠ ਤੋਂ ਬੋਲੀ ਮੁੱਖ +GenericName[pl]=Program obsługujący syntezator mowy +GenericName[pt]=Interface de Texto para Fala +GenericName[pt_BR]=Interface para a Conversão de Texto para Fala +GenericName[ru]=Интерфейс к средствам синтеза речи +GenericName[sk]=Rozhranie text-na-reč +GenericName[sl]=Vmesnik »besedila v govor« +GenericName[sr]=Интерфејс за текст-у-говор +GenericName[sr@Latn]=Interfejs za tekst-u-govor +GenericName[sv]=Text-till-tal gränssnitt +GenericName[ta]=பேச்சில் இருந்து உரை முன்னணி +GenericName[tg]=Интерфейс барои таҳлили овоз +GenericName[th]=ฟร้อนเอนด์แปลงข้อความเป็นคำพูด +GenericName[tr]= Metinden Konuşmaya Önyüzü +GenericName[uk]=Інтерфейс синтезу мовлення з тексту +GenericName[vi]=Giao diện chuyển Văn bản thành Tiếng nói +GenericName[zh_CN]=文本到语音前端 +GenericName[zh_TW]=文字轉語音前端程式 +Categories=Qt;KDE;Accessibility;Utility; diff --git a/ksayit/src/ksayit.h b/ksayit/src/ksayit.h new file mode 100644 index 0000000..6da1465 --- /dev/null +++ b/ksayit/src/ksayit.h @@ -0,0 +1,364 @@ +/*************************************************************************** + ksayit.h - description + ------------------- + begin : Son Aug 10 13:26:57 EDT 2003 + copyright : (C) 2003 by Robert Vogl + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef KSAYIT_H +#define KSAYIT_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +using namespace std; + +// include files for Qt +#include <qstringlist.h> +#include <qclipboard.h> + +// include files for KDE +#include <kapplication.h> +#include <kmainwindow.h> +#include <kaccel.h> +#include <kaction.h> +#include <kactionclasses.h> +#include <kurl.h> +#include <dcopobject.h> +#include <kbookmarkmanager.h> +#include <kbookmarkmenu.h> + +// App specific includes + +// appended to $HOME +#define KSAYIT_BOOKMARKXMLFILE "/.ksayitbookmarks.xml" + +// forward declaration of the KSayIt classes +class KSayItViewImpl; +class DocTreeViewImpl; +class KSayItSystemTray; +class FXPluginHandler; +class EffectStack; +class KTTSDLib; +class KSayItBookmarkHandler; + +/** + * The base class for KSayIt application windows. It sets up the main + * window and reads the config file as well as providing a menubar, toolbar + * and statusbar. An instance of KSayItView creates the center view. + * KSayItApp reimplements the methods that KMainWindow provides for main window handling and supports + * full session management as well as using KActions. + * @see KMainWindow + * @see KApplication + * @see KConfig + * + * @author Robert Vogl + */ +class KSayItApp : public KMainWindow, public DCOPObject +{ + Q_OBJECT + K_DCOP + +public: + /** construtor of KSayItApp, calls all init functions to create the application. + */ + KSayItApp(QWidget* parent=0, const char* name=0, WFlags f=0, + const QCString &objID=0); + ~KSayItApp(); + +k_dcop: + /** DCOP interface for say operation + \param msg The text to speak. + */ + ASYNC dcopSayText(QString msg); + + /** DCOP interface for stop operation + */ + ASYNC dcopStop(); + + /** DCOP interface to say DocBook file + */ + ASYNC dcopSayXmlFile(KURL url); + + +signals: + /** emitted when the Configuration was modified + */ + void signalConfigChanged(); + +private slots: + /** Puts the given text on the Job-Stack of KTTSD. + * \param text The text to say. + */ + void slotSetText(const QString &text); + + /** Called from the ListView widget after one or many + * 'setText'-Calls. Starts to say the text. + */ + void slotSayNode(); + + /** Called when a node in the treeview was clicked and + * new content in the edit window must be shown. + * \str The new content of the EditView. + */ + void slotTreeViewChanged(const QString &str); + + /** save general Options like all bar positions and status as well as the geometry to + * the configuration file. + */ + void slotSaveOptions(); + + /** closes the windows , then quits the application. + */ + void slotFileQuit(); + + /** changes the statusbar contents for the standard label permanently, used to indicate + * current actions. + * @param text the text that is displayed in the statusbar + */ + void slotStatusMsg(const QString &text); + + /** opens the Preferences-Dialog. + */ + void slotPreferences(); + + /** activated if "say" from tray was clicked. + */ + void slotSayClipboard(); + + /** activated if "say" from app-window was clicked. + */ + void slotSayText(); + + /** activated if "shut up" was clicked. + */ + void slotStopActivated(); + + /** activated if "pause" was clicked. + */ + void slotPauseActivated(); + + /** activated if "next sentence" was clicked. + */ + void slotNextSentenceActivated(); + + /** activated if "previous sentence" was clicked. + */ + void slotPrevSentenceActivated(); + + /** called if text processing was finished. + */ + void slotFinished(); + + /** called to enable the copy/cut action, if text is selected in the TextEdit-View + \param enable Enable actions if true, disable actions if false. + */ + void slotEnableCopyCut(bool enable); + + /** sets the Caption of the MainWindow */ + void slotSetCaption(const QString &caption); + + /** called when the Text was changed. + * \param empty True if the TextEdit view is empty. + */ + void slotTextChanged(bool empty); + + /** enabled/disables the textedit window; + * \param enable true=enabled, false=disabled + */ + void slotEnableTextedit(bool enable); + + /** toggles the statusbar + */ + void slotToggleStatusBar(); + + /** Called when the ToolBar shall be configured by the user. + */ + void slotConfigureToolbar(); + + /** Called to add a bookmark. + */ + void slotAddBookmark(); + + /** Called to delete a bookmark + */ + void slotDeleteBookmark(const QString &url, const QString &title); + + /** Called to edit bookmarks. + */ + void slotEditBookmarks(); + + /** Called from slotConfigureToolbar() if we have a new ToolBar-configuration. + */ + void slotNewToolbarConfig(); + + /** called whenever the content of the clipboard changes. + * Checks if the content of the Clipboard is of type text/plain. + * Disables and enables the SystemTray-object. + */ + void slotClipboardChanged(); + + /** Deletes the content of the Textview. + */ + void slotClear(); + + /** Hides the MainWindow + */ + void slotCloseMainWindow(); + + /** Dialog to edit the Key associations + */ + void slotEditKeys(); + + /** Open file action + */ + void slotFileOpen(); + + /** Save file + */ + void slotFileSave(); + + /** Save file as + */ + void slotFileSaveAs(); + + /** Called, when the TTS Library has finished processing. + */ + void slotTTSFinished(); + + /** Edit mode switched on/off. + */ + void slotEditToggled(); + + /** + * Catches the signal from the TreeView object + * and forwards it to the BookmarkHandler object. + */ + void slotNotifyBookmarkHandler(const QString &ID, const QString &title); + + /** + * Copies the content of the current bookmark file to the + * file designated by \p newname and install a new + * BookmarkHandler. + * \param newname The name of the new bookmark file. + */ + void slotChangeBookmarkFilename(const QString &newname); + + /** Loads bookmark file corresponding to the given file. + * \param newname The name of the new file. + */ + void slotSetBookmarkFilename(const QString &newname); + +public: + /** + * Selects the item with the given ID in the TreeView. + * \param ID The ID of the item to select. + * \param title The title of the bookmark. + * \returns <tt>QString::null</tt>, if the operation was successfull, + * an error message, if the ID was not found. + */ + QString setItemByBookmark( const QString &ID, const QString &title ); + +private: // Methods + /** read general Options again and initialize all variables. + */ + void readOptions(); + + /** initializes the KActions of the application */ + void initActions(); + + /** sets up the statusbar for the main window by initialzing a statuslabel. + */ + void initStatusBar(); + + /** + */ + void initBookmarkManager(const QString &filename); + + /** creates the centerwidget of the KTMainWindow instance and sets it as the view. + */ + void initView(); + + /** resets the editor. Do not create an empty document. + */ + void resetView(); + + /** start to say the text on the KTTSD's Job-Stack. + */ + void sayActivated(); + + /** reimplemented from baseclass + */ + virtual void closeEvent(QCloseEvent *ce); + + /** disable/enable Actions. + * \param actions An OR'ed integer of enum ACTIONS. A '1' is supposed + * as 'Action enabled'. + */ + void setActions(int actions); + + /** + * Returns the absolute pathname of the given bookmarkfile. + * This is the first KDE resource directory \p (share/apps) in which + * the user has write permissions. The relative path is + * \p ksayit/ksayit_bookmarks/. + * \param filename The name of the bookmark file. + * \returns The absolute pathname of the given bookmark file. + * Returns \p QString::null if the operation was not successfull. + */ + QString getBookmarkDir(const QString &filename); + + +private: + KConfig *config; + KSayItViewImpl *view; + KSayItSystemTray *tray; + EffectStack *es; + DocTreeViewImpl *treeview; + KBookmarkManager *bkManager; + KSayItBookmarkHandler *bkHandler; + KBookmarkMenu *bkMenu; + + // KAction pointers + KToggleAction *statusBarAction; + KAction *say; + KAction *pause; + KAction *shutup; + KAction *next_sentence; + KAction *prev_sentence; + KAction *clear; + KAction *copy; + KAction *cut; + KAction *paste; + KAction *open; + KAction *save; + KAction *saveAs; + KAction *preferences; + KToggleAction *edit; + KActionMenu *bookmarkmenu; + + // Misc stuff + QClipboard *cb; + QString clip; + KTTSDLib *m_kttslib; + FXPluginHandler *m_fxpluginhandler; + bool m_ap_saying; + bool m_ap_paused; + bool m_textview_empty; + bool m_enableChangeNotifications; + QString m_currentBookmarkFile; + +}; + +#endif // KSAYIT_H diff --git a/ksayit/src/ksayit_fxplugin.h b/ksayit/src/ksayit_fxplugin.h new file mode 100644 index 0000000..9956df6 --- /dev/null +++ b/ksayit/src/ksayit_fxplugin.h @@ -0,0 +1,88 @@ +// +// C++ Interface: fxplugin +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef FXPLUGIN_H +#define FXPLUGIN_H + +// QT includes +#include <qobject.h> +#include <qstring.h> + +// KDE includes +#include <kapplication.h> +#include <arts/kartsserver.h> +#include <arts/artsflow.h> + +using namespace Arts; + +// App specific includes + +/** FXPlugin is an abstract class to create effect plugins for KSayIt. + * If you would like to implement a plugin, simply make a class + * derived from FXPlugin, include 'ksayit_fxplugin.h' and reimplement all the + * pure virtual functions provided herein. + * *Appl is a pointer to the main application as delivered by \p KApplication::kApplication(). + * It can be used for any reason i.e. to install a Qt translator.\n + \author Robert Vogl + */ +class FXPlugin : public QObject +{ +// Q_OBJECT +public: + FXPlugin(QObject *parent=0, const char* name=0){}; + + /** Sets the Main application object. Useful for config objects etc. + */ + virtual void setApplication(KApplication *Appl) = 0; + + /** Returns the name of the plugin. This name is the unique identifier + * for the plugin. A expressive name is recommended because this name + * may be shown to the user, i.e. in a configuration dialog. + * The PluginHandler internally references to each effect plugin by this name.\n + * Has to be reimplemented by the plugin implementation. + */ + virtual QString getName_KS() const = 0; + + /** Returns the description of the plugin.\n + * Has to be reimplemented by the plugin implementation. + */ + virtual QString getDescription_KS() const = 0; + + /** Shows the GUI to configure the plugin. The configuration can to be + * stored in the global configuration file of KSayIt.\n + * Has to be reimplemented by the plugin implementation. + */ + virtual bool showGUI_KS() = 0; + + /** Activates the effect i.e. puts it on the soundservers stack.\n + * Returns the ID of the activated effect. + * Has to be reimplemented by the plugin implementation. + \param server A pointer to the aRts soundserver instance. + \param fx_stack A pointer to the effect stack of the soundserver. + */ + virtual long activate_KS(KArtsServer *server, + StereoEffectStack *fx_stack) const = 0; + + /** Deactivates the effect i.e. removes it from the effect stack.\n + * Has to be reimplemented by the plugin implementation. + \param fx_stack A pointer to the effect stack of the soundserver. + \param EffectID The ID of the effect as returned by \p activate_KS(). + */ + virtual bool deactivate_KS(StereoEffectStack *fx_stack, + long EffectID) const = 0; + +}; + + + +#endif + + diff --git a/ksayit/src/ksayit_ttsplugin.h b/ksayit/src/ksayit_ttsplugin.h new file mode 100644 index 0000000..1035993 --- /dev/null +++ b/ksayit/src/ksayit_ttsplugin.h @@ -0,0 +1,166 @@ +// +// C++ Interface: ksayit_ttsplugin +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#ifndef KSAYIT_TTSPLUGIN +#define KSAYIT_TTSPLUGIN + +// QT includes +#include <qobject.h> +#include <qwidget.h> +#include <qframe.h> +#include <qstring.h> + + +// KDE includes +#include <kapplication.h> + +// App specific includes + + +#include "kttsdlib.h" + +/** TTSPlugin is an abstract class to integrate various TTS systems as plugins + * (Shared Objects) into KSayIt. + * If you would like to implement a plugin, simply make a class + * inherited from TTSPlugin, include 'ksayit_ttsplugin.h' and reimplement all the + * pure virtual functions provided herein. + * In addition you must implement two class factories:\n + * \p createPlugin() returns a pointer to an instance of your class. + * The Plugin Handler of KSayIt calls this function with a parameter pointing + * to the main application instance, as delivered by \p KApplication::kApplication(). + * This pointer can be used for any reason i.e. to install a Qt translator.\n + * An instance of your class should be deleted by use of \p destroyPlugin().\n + * Example: + \code + extern "C" + { + TTSPlugin* createPlugin(KApplication *Appl) + { + return new MyNewPlugin(Appl); + } + + void destroyPlugin(TTSPlugin* p) + { + delete p; + } + }; + \endcode + * KSayIt expects two Qt-signals from the plugin:\n + * \p signalPluginFinished() must be emitted when the plugin is finished, + * i.e. a task to speak text has been finished.\n + * \p signalPluginFailed() is optional and shall emitted if the processing + * of the plugin has been failed by any reason. + \author Robert Vogl + */ + +class TTSPlugin : public QObject +{ +protected: + TTSPlugin(QObject *parent, const char *name) : QObject(parent, name){}; + +public: + /** Returns the name of the plugin. This name is the unique identifier + * for the plugin. A expressive name is recommended because this name + * may be shown to the user, i.e. in a configuration dialog. + * The PluginHandler internally references to each TTS plugin by this name.\n + * Has to be reimplemented by the plugin implementation. + */ + virtual QString getName_KS() const = 0; + + /** Returns the description of the plugin.\n + * Has to be reimplemented by the plugin implementation. + */ + virtual QString getDescription_KS() const = 0; + + /** Returns the supported control actions of the plugin. + * It is represented as an OR'ed value of enum \pACTIONS. + */ + virtual int getActions_KS() = 0; + + /** Returnes a pointer to the GUI widget to configure the plugin.\n + * Will be deleted by the PluginHandler.\n + * \param frame A pointer to the QFrame object in which the dialog will + * be embedded. + */ + virtual const QWidget* getGUI_KS(QFrame *frame) = 0; + + /** Let the plugin (re)load its configuration + */ + virtual void reloadConfiguration_KS() = 0; + + /** Called from the Plugin Handler if the "OK" Button of the main + * configuartion dialog was clicked.\n + * Returns false if something went wrong otherwise true. + */ + virtual bool saveWasClicked_KS() const = 0; + + /** This method speeches the given Text.\n + * If the used TTS system outputs to a sound file + * (i.e. a .wav file) it may return its path and filename to KSayIt. + * In this case, KSayIt uses a built-in audio player to play back + * the file via aRts.\n + * If this plugin provides its own audio output mechanisms, then return + * \p QString::null.\n + * The TTS processing shall be implemented non-blocking, i.e. this function has + * to return a valid string as soon as possible, before the typically time + * consuming TTS processing starts. The synchronization with KSayIt shall + * be performed by the status flags (see \p getStatus_KS()). + * \param text The text to speach. + */ + virtual QString sayText_KS(const QString &text) = 0; + + /** Returns an OR'ed value of status bits of the plugin.\n + * Currently only \p TTS::AUDIOFILE is defined.\n This + * bit indicates that the plugin is configured to output + * to an audiofile.\n + * If configurable, \p TTS::AUDIOFILE must toggle synchronously with + * the setup widget. + * This flag must have a valid value during the overall lifetime + * of the plugin object. + */ + virtual int getStatus_KS() const = 0; + + /** Processes the stop event from KSayIt. + */ + virtual void stop_KS() = 0; + + /** Processes the pause event from KSayIt. + */ + virtual void pause_KS() = 0; + + /** Processes resume event after pause from KSayIt. + */ + virtual void resume_KS() = 0; + + /** May be used as a fast forward function, e.g. + * jump to the next sentence, paragraph or whatever. + */ + virtual void ffwd_KS() = 0; + + /** May be used as a rewind function, e.g. + * jumb back to the beginning of the current paragraph, + * repeat previous sentence or whatever. + */ + virtual void frev_KS() = 0; + +}; + +// Types of the class factories +typedef TTSPlugin* (*create_ttspi)(KApplication *Appl); +typedef void (*destroy_ttspi)(TTSPlugin *p); + + + + +#endif + + diff --git a/ksayit/src/ksayitbookmarkhandler.cpp b/ksayit/src/ksayitbookmarkhandler.cpp new file mode 100644 index 0000000..b52cdd7 --- /dev/null +++ b/ksayit/src/ksayitbookmarkhandler.cpp @@ -0,0 +1,238 @@ +// +// C++ Implementation: ksayitbookmarkhandler +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@web.de>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +// Qt include +#include <qregexp.h> + +// KDE includes +#include <kdebug.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kurl.h> + +// App specific includes +#include "ksayitbookmarkhandler.h" +#include "ksayit.h" + +KSayItBookmarkHandler::KSayItBookmarkHandler(KBookmarkManager *bkManager, KSayItApp* parent) + : KBookmarkOwner(), m_bkManager(bkManager), m_parent(parent) +{ + m_ID = QString::null; + m_title = QString::null; +} + +KSayItBookmarkHandler::~KSayItBookmarkHandler() +{ +} + + +void KSayItBookmarkHandler::notifyBookmarkHandler(const QString &ID, const QString &title) +{ + kdDebug(100200) << "KSayItBookmarkHandler::notifyBookmarkManager()" << endl; + + m_ID = ID; + m_title = title; +} + + +void KSayItBookmarkHandler::openBookmarkURL(const QString &url) +{ + kdDebug(100200) << "KSayItBookmarkHandler::openBookmarkURL(" << url << ")" << endl; + + QString l_url = url; + QString title = QString::null; + QString type = l_url.section( "://", 0, 0 ); + QString ID = l_url.section( QRegExp("/+"), 1, 1 ); + QString err = QString::null; + + // Some checks + if ( type != "ksayit" ){ + err += i18n("This is not a KSayIt bookmark.\n"); + } + + // get title + KBookmarkGroup bkRoot = m_bkManager->root(); + if ( bkRoot.isNull() ) + return; + + KBookmark bookmark; + KBookmarkGroup group; + bool found = recursiveGetBkByURL( bookmark, group, bkRoot, url ); + if ( found ){ + title = bookmark.text(); + } + + QString result = QString::null; + result = m_parent->setItemByBookmark( ID, title ); + if ( !result.isNull() ){ + KMessageBox::sorry( 0, result, i18n("Bookmark not found") ); + } +} + + +QString KSayItBookmarkHandler::currentTitle() const +{ + kdDebug(100200) << "KSayItBookmarkHandler::currentTitle()" << endl; + + QString result; + if ( m_title.isEmpty()){ + result = i18n("untitled"); + } else { + result = m_title; + } + + return result; +} + + +QString KSayItBookmarkHandler::currentURL() const +{ + kdDebug(100200) << "KSayItBookmarkHandler::currentURL()" << endl; + + QString url; + url = "ksayit://" + m_ID; + + return url; +} + + +void KSayItBookmarkHandler::deleteBookmark(const QString &url, const QString &title) +{ + kdDebug(100200) << "KSayItBookmarkHandler::deleteBookmark()" << endl; + + KBookmarkGroup bkRoot = m_bkManager->root(); + if ( bkRoot.isNull() ) + return; + + // search bookmark by URL + KBookmark bookmark; + KBookmarkGroup group; + bool found = false; + found = recursiveGetBkByURL( bookmark, group, bkRoot, url ); + if ( found ){ + group.deleteBookmark( bookmark ); + m_bkManager->emitChanged( group ); + m_bkManager->save(); // make persistent + return; + } + + // if not found, search bookmark by title + int qty = 0; + qty = recursiveGetBkByTitle( bookmark, group, bkRoot, title ); + if ( qty == 1 ){ + QString url = bookmark.url().url(); + QString title = bookmark.text(); + group.deleteBookmark( bookmark ); + m_bkManager->emitChanged( group ); + m_bkManager->save(); // make persistent + } +} + + +bool KSayItBookmarkHandler::recursiveGetBkByURL( + KBookmark &bookmark, + KBookmarkGroup &group, + const KBookmarkGroup &bkGroup, + const QString &url) +{ + KBookmark bkNext; + bool found = false; + + KBookmark bk = bkGroup.first(); + while ( !bk.isNull() && !bk.isSeparator() ){ + if ( bk.isGroup() ){ + // recursive call + found = recursiveGetBkByURL( bookmark, group, bk.toGroup(), url ); + if ( found ) + return true; + bkNext = bkGroup.next( bk ); + } else { + QString l_url = bk.url().url(); + if ( l_url == url ){ + bookmark = bk; + group = bkGroup; + return true; + } + bkNext = bkGroup.next( bk ); + } + bk = bkNext; + } + return false; +} + + +int KSayItBookmarkHandler::recursiveGetBkByTitle( + KBookmark &bookmark, + KBookmarkGroup &group, + const KBookmarkGroup &bkGroup, + const QString &title) +{ + KBookmark bkNext; + int qty = 0; + + KBookmark bk = bkGroup.first(); + while ( !bk.isNull() && !bk.isSeparator() ){ + if ( bk.isGroup() ){ + // recursive call + qty += recursiveGetBkByTitle( bookmark, group, bk.toGroup(), title ); + bkNext = bkGroup.next( bk ); + } else { + QString l_title = bk.text(); + if ( l_title == title ){ + bookmark = bk; + group = bkGroup; + qty++; + } + bkNext = bkGroup.next( bk ); + } + bk = bkNext; + } + return qty; +} + + +void KSayItBookmarkHandler::traverseBookmarks(KBookmarkGroup bkGroup) +{ + kdDebug(100200) << "### KSayItBookmarkHandler::traverseBookmarks()" << endl; + + if( bkGroup.isNull() ) + return; + + KURL url; + QString title; + KBookmark bkNext, bkPrev, bkNew; + + KBookmark bk = bkGroup.first(); + while ( !bk.isNull() && !bk.isSeparator() ){ + if ( bk.isGroup() ){ + traverseBookmarks( bk.toGroup() ); // recursive call + bkNext = bkGroup.next( bk ); + } else { + url = bk.url(); + title = bk.text(); + bkNext = bkGroup.next( bk ); + bkPrev = bkGroup.previous( bk ); + if ( bkPrev.isNull() ) // no predecessor + bkPrev = bk; + + // Modifications on URL/Title BEGIN + // + // Modifications on URL/Title END + + bkNew = bkGroup.addBookmark( m_bkManager, title, url, QString::null, false ); + bkGroup.moveItem( bkNew, bkPrev ); + bkGroup.deleteBookmark( bk ); + } + bk = bkNext; + } + m_bkManager->save(); // make persistent +} diff --git a/ksayit/src/ksayitbookmarkhandler.h b/ksayit/src/ksayitbookmarkhandler.h new file mode 100644 index 0000000..edab6d6 --- /dev/null +++ b/ksayit/src/ksayitbookmarkhandler.h @@ -0,0 +1,120 @@ +// +// C++ Interface: ksayitbookmarkhandler +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@web.de>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef KSAYITBOOKMARKHANDLER_H +#define KSAYITBOOKMARKHANDLER_H + +// Qt includes +#include <qstring.h> + +// KDE includes +#include <kbookmarkmanager.h> + + +class KSayItApp; + +/** + Each of the objects in the TreeView that can be bookmarked has an unique ID. + The "URL" is to be created as follows: \p ksayit://filename/ID.\n + The "Title" is either the content of column 0 of the TreeView or the 32nd leading + charcters of the text (e.g. if the item references to a paragraph). +@author Robert Vogl +*/ +class KSayItBookmarkHandler : public KBookmarkOwner +{ +public: + KSayItBookmarkHandler(KBookmarkManager *bkManager=0, KSayItApp* parent=0); + virtual ~KSayItBookmarkHandler(); + +public: + /** + * Reimplemented from base class.\n + * Called when a bookmark in the menu was clicked. + * \param url The URL of the selected bookmark. + */ + void openBookmarkURL(const QString &url); + + /** + * Reimplemented from base class.\n + * Returns the Title when a new bookmark is about to be created. + * \returns The title of the bookmark. + */ + QString currentTitle() const; + + + /** + * Reimplemented from base class.\n + * Returns the URL when a new bookmark is about to be created. + * \returns The URL of the bookmark. + */ + QString currentURL() const; + + /** + * Sets ID and title of the current TreeView item. + * \param ID The unique ID of the item. + * \param title The bookmark title of the item. + */ + void notifyBookmarkHandler(const QString &ID, const QString &title); + + /** + * Deletes the bookmark designated by the given url. + * \param url The url of the bookmark. + */ + void deleteBookmark(const QString &url, const QString &title); + + /** + * Iterates recursively through all bookmarks below the + * given group. + * \param bkGroup The KBookmarkGroup to start. + */ + void traverseBookmarks(KBookmarkGroup bkGroup); + +private: + /** + * Searches the Bookmark designted by its URL. + * \param bookmark A reference that will contain the search result (bookmark). + * \param group A reference that will contain the search result + * (the group the found bookmark belongs to). + * \param bkGroup The root-bookmark from which the search will start + * (usually the topmost bookmark in the tree). + * \param url The URL of the bookmark to search for (including <tt>ksayit://</tt>). + * \returns \em true, if the bookmark was found, \em false, if not. + */ + bool recursiveGetBkByURL( + KBookmark &bookmark, + KBookmarkGroup &group, + const KBookmarkGroup &bkGroup, + const QString &url); + + /** + * Searches the Bookmark designted by its URL. + * \param bookmark A reference that will contain the search result (bookmark). + * \param group A reference that will contain the search result + * (the group the found bookmark belongs to). + * \param bkGroup The root-bookmark from which the search will start + * (usually the topmost bookmark in the tree). + * \param title The title of the bookmark to search for. + * \returns Number of bookmarks with the given title. + */ + int recursiveGetBkByTitle( + KBookmark &bookmark, + KBookmarkGroup &group, + const KBookmarkGroup &bkGroup, + const QString &title); +private: + QString m_ID; + QString m_title; + KBookmarkManager *m_bkManager; + KSayItApp *m_parent; + +}; + +#endif diff --git a/ksayit/src/ksayitsystemtray.cpp b/ksayit/src/ksayitsystemtray.cpp new file mode 100644 index 0000000..82bda61 --- /dev/null +++ b/ksayit/src/ksayitsystemtray.cpp @@ -0,0 +1,356 @@ +/*************************************************************************** + ksayitsystemtray.cpp - description + ------------------- + begin : Die Sep 2 2003 + copyright : (C) 2003 by Robert Vogl + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ +#include <iostream> + +// QT includes +#include <qtranslator.h> + +// KDE includes +#include <kglobal.h> +#include <klocale.h> + +// App specific includes +#include "ksayitsystemtray.h" + +KSayItSystemTray::KSayItSystemTray(QWidget *parent, const char *name) + : KSystemTray(parent,name) +{ + initActions(); + changeState( StateCLIPEMPTY::Instance() ); +} + +KSayItSystemTray::~KSayItSystemTray() +{ + delete StateWAIT::Instance(); + delete StateSAY::Instance(); + delete StateCLIPEMPTY::Instance(); +} + +void KSayItSystemTray::initActions() +{ + // Context-menu + menu = this->contextMenu(); + help = new KHelpMenu(this, kapp->aboutData(), false, actionCollection()); + // Standard actions + settings = KStdAction::preferences(this, SLOT(slotPreferences()), actionCollection()); + help_about = KStdAction::aboutApp(help, SLOT(aboutApplication()), actionCollection()); + help_kde = KStdAction::aboutKDE(help, SLOT(aboutKDE()), actionCollection()); + + // User defined actions + say = new KAction(i18n("Say"), + "player_play", + 0, + this, SLOT (slotSayActivated()), + actionCollection(), + "say_it"); + + shutup = new KAction(i18n("Shut Up"), + "player_stop", + 0, + this, SLOT (slotStopActivated()), + actionCollection(), + "shut_up"); + + pause = new KAction (i18n("Pause"), + "player_pause", + 0, + this, SLOT (slotPauseActivated()), + actionCollection(), + "pause"); + + next_sentence = new KAction (i18n("Next Sentence"), + "2rightarrow", + 0, + this, SLOT (slotNextSentenceActivated()), + actionCollection(), + "next_sentence"); + + + prev_sentence = new KAction (i18n("Previous Sentence"), + "2leftarrow", + 0, + this, SLOT(slotPrevSentenceActivated()), + actionCollection(), + "prev_sentence"); + + // Actions -> Context-menu + settings->plug(menu); menu->insertSeparator(); + say->plug(menu); + shutup->plug(menu); + pause->plug(menu); + next_sentence->plug(menu); + prev_sentence->plug(menu); menu->insertSeparator(); + help_about->plug(menu); + help_kde->plug(menu); + + // default enables/disables + say ->setEnabled(false); + shutup ->setEnabled(false); + pause ->setEnabled(false); + next_sentence->setEnabled(false); + prev_sentence->setEnabled(false); +} + + +void KSayItSystemTray::slotPreferences() +{ + // call Preferences + emit signalCallPreferences(); +} + +void KSayItSystemTray::mousePressEvent(QMouseEvent *me) +{ + _state->mousePressEvent(this, me); +} + +void KSayItSystemTray::mouseReleaseEvent(QMouseEvent *me) +{ + _state->mouseReleaseEvent(this, me); +} + +void KSayItSystemTray::slotSayActivated() +{ + // start to say content of clipboard + emit signalSayActivated(); +} + +void KSayItSystemTray::slotStopActivated() +{ + // stop saying + emit signalShutUpActivated(); +} + +void KSayItSystemTray::slotPauseActivated() +{ + // pause saying + emit signalPauseActivated(); +} + +void KSayItSystemTray::slotNextSentenceActivated() +{ + // next sentence + emit signalNextActivated(); +} + +void KSayItSystemTray::slotPrevSentenceActivated() +{ + // previous sentence + emit signalPrevActivated(); +} + + +void KSayItSystemTray::changeState(State *state) +{ + _state = state; + _state->setContext(this); +} + +void KSayItSystemTray::setActions(bool sayEnabled, bool pauseEnabled, bool shutupEnabled, + bool nextEnabled, bool prevEnabled) +{ + say ->setEnabled(sayEnabled); + pause ->setEnabled(pauseEnabled); + shutup ->setEnabled(shutupEnabled); + next_sentence->setEnabled(nextEnabled); + prev_sentence->setEnabled(prevEnabled); +} + + +void KSayItSystemTray::normalMousePressEvent(QMouseEvent *e) +{ + KSystemTray::mousePressEvent(e); +} + +void KSayItSystemTray::normalMouseReleaseEvent(QMouseEvent *e) +{ + KSystemTray::mouseReleaseEvent(e); +} + +void KSayItSystemTray::sayClipboard() +{ + emit signalSayClipboard(); +} + + + + +//////////////////////////////////////////// +State::State(){ +} +State::~State(){ +} + +void State::mousePressEvent(KSayItSystemTray *caller, QMouseEvent *e) +{ + // reimplemented by subclasses +} + +void State::mouseReleaseEvent(KSayItSystemTray *caller, QMouseEvent *e) +{ + // reimplemented by subclasses +} + +void State::setContext(KSayItSystemTray *caller) +{ + // reimplemented by subclasses +} + +void State::changeState(KSayItSystemTray *caller, State *state) +{ + caller->changeState(state); +} + +void State::say(KSayItSystemTray *caller) +{ + caller->sayClipboard(); +} + +void State::mousePressEventCall(KSayItSystemTray *caller, QMouseEvent *e) +{ + caller->normalMousePressEvent(e); +} + +void State::mouseReleaseEventCall(KSayItSystemTray *caller, QMouseEvent *e) +{ + caller->normalMouseReleaseEvent(e); +} + + +//////////////////////////////////////////// +StateWAIT::StateWAIT(){ + m_traypixmap = KGlobal::iconLoader()->loadIcon("ksayit", KIcon::Toolbar); +} +StateWAIT::~StateWAIT(){ +} +StateWAIT* StateWAIT::_instance = 0; + +StateWAIT* StateWAIT::Instance() +{ + if (_instance == 0){ + _instance = new StateWAIT(); + } + return _instance; +} + +void StateWAIT::setContext(KSayItSystemTray *caller) +{ + caller->setPixmap( m_traypixmap ); +} + +void StateWAIT::mousePressEvent(KSayItSystemTray *caller, QMouseEvent *e) +{ + if (e->button()==LeftButton){ // left Mouse-button pressed + QWidget::mousePressEvent(e); // do nothing (see mouseReleaseEvent) + } else { + mousePressEventCall(caller, e); // normal mouse-handling + } +} + +void StateWAIT::mouseReleaseEvent(KSayItSystemTray *caller, QMouseEvent *e) +{ + if (e->button()==LeftButton){ // left Mouse-button released + say(caller); + } else { + mouseReleaseEventCall(caller, e); // normal mouse-handling + } +} + + + +//////////////////////////////////////////// +StateSAY::StateSAY(){ + m_traypixmap = KGlobal::iconLoader()->loadIcon("ksayit_talking", KIcon::Toolbar); +} +StateSAY::~StateSAY(){ +} +StateSAY* StateSAY::_instance = 0; + +StateSAY* StateSAY::Instance() +{ + if (_instance == 0){ + _instance = new StateSAY(); + } + return _instance; +} + +void StateSAY::setContext(KSayItSystemTray *caller) +{ + caller->setPixmap( m_traypixmap ); +} + +void StateSAY::mousePressEvent(KSayItSystemTray *caller, QMouseEvent *e) +{ + if (e->button()==LeftButton){ // left Mouse-button pressed + QWidget::mousePressEvent(e); // do nothing (see mouseReleaseEvent) + } else { + mousePressEventCall(caller, e); // normal mouse-handling + } +} + +void StateSAY::mouseReleaseEvent(KSayItSystemTray *caller, QMouseEvent *e) +{ + if (e->button()==LeftButton){ // left Mouse-button released + QWidget::mouseReleaseEvent(e); // do nothing (see mouseReleaseEvent) + } else { + mouseReleaseEventCall(caller, e); // normal mouse-handling + } +} + + + + +//////////////////////////////////////////// +StateCLIPEMPTY::StateCLIPEMPTY(){ + m_traypixmap = KGlobal::iconLoader()->loadIcon("ksayit_clipempty", KIcon::Toolbar); +} +StateCLIPEMPTY::~StateCLIPEMPTY(){ +} +StateCLIPEMPTY* StateCLIPEMPTY::_instance = 0; + +StateCLIPEMPTY* StateCLIPEMPTY::Instance() +{ + if (_instance == 0){ + _instance = new StateCLIPEMPTY(); + } + return _instance; +} + +void StateCLIPEMPTY::setContext(KSayItSystemTray *caller) +{ + caller->setPixmap( m_traypixmap ); +} + +void StateCLIPEMPTY::mousePressEvent(KSayItSystemTray *caller, QMouseEvent *e) +{ + if (e->button()==LeftButton){ // left Mouse-button pressed + QWidget::mousePressEvent(e); // do nothing (see mouseReleaseEvent) + } else { + mousePressEventCall(caller, e); // normal mouse-handling + } +} + +void StateCLIPEMPTY::mouseReleaseEvent(KSayItSystemTray *caller, QMouseEvent *e) +{ + if (e->button()==LeftButton){ // left Mouse-button released + QWidget::mouseReleaseEvent(e); // do nothing (see mouseReleaseEvent) + } else { + mouseReleaseEventCall(caller, e); // normal mouse-handling + } +} + + +#include "ksayitsystemtray.moc" diff --git a/ksayit/src/ksayitsystemtray.h b/ksayit/src/ksayitsystemtray.h new file mode 100644 index 0000000..90db592 --- /dev/null +++ b/ksayit/src/ksayitsystemtray.h @@ -0,0 +1,228 @@ +/*************************************************************************** + ksayitsystemtray.h - description + ------------------- + begin : Die Sep 2 2003 + copyright : (C) 2003 by Robert Vogl + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef KSAYITSYSTEMTRAY_H +#define KSAYITSYSTEMTRAY_H + +// QT includes +#include <qwidget.h> +#include <qpixmap.h> + +// KDE includes +#include <kapplication.h> +#include <ksystemtray.h> +#include <kpopupmenu.h> +#include <kaction.h> +#include <kmenubar.h> +#include <khelpmenu.h> +#include <kiconloader.h> + +// forward declarations +class State; + +/** + *@author Robert Vogl + */ +class KSayItSystemTray : public KSystemTray { + Q_OBJECT + + friend class State; + +public: + KSayItSystemTray(QWidget *parent=0, const char *name=0); + ~KSayItSystemTray(); + +signals: + /** Signal emitted if configuration has been changed + */ + void signalCallPreferences(); + + /** Signal emitted if the Tray icon was clicked. + */ + void signalSayClipboard(); + + /** Signal emitted by the control actions + */ + void signalSayActivated(); + + void signalShutUpActivated(); + + void signalPauseActivated(); + + void signalNextActivated(); + + void signalPrevActivated(); + +public slots: + /** opens the Preferences-Dialog + */ + void slotPreferences(); + + /** activated if "say" was clicked + */ + void slotSayActivated(); + + /** activated if "shut up" was clicked + */ + void slotStopActivated(); + + /** activated if "pause" was clicked + */ + void slotPauseActivated(); + + /** activated if "next sentence" was clicked + */ + void slotNextSentenceActivated(); + + /** activated if "previous sentence" was clicked + */ + void slotPrevSentenceActivated(); + +public: + /** Changes the state of the statemachine + */ + void changeState(State *state); + + /** Enables/Diasabled the actions in the menu + */ + void setActions(bool sayEnabled, bool pauseEnabled, bool shutupEnabled, + bool nextEnabled, bool prevEnabled); + +protected: // Methods + /** Reimplementation from base class + */ + void mousePressEvent(QMouseEvent *); + + /** Reimplementation from base class + */ + void mouseReleaseEvent(QMouseEvent *); + + /** KSystemTray default mouse handling + */ + void normalMousePressEvent(QMouseEvent *e); + + /** KSystemTray default mouse handling + */ + void normalMouseReleaseEvent(QMouseEvent *e); + + /** Called if the Tray icon was clicked. + */ + void sayClipboard(); + +private: // Methods + /** initializes the KActions of the application */ + void initActions(); + +public: + KAction *say; + KAction *shutup; + KAction *pause; + KAction *next_sentence; + KAction *prev_sentence; + +private: + KPopupMenu *menu; + KHelpMenu *help; + KAction *settings; + KAction *help_about; + KAction *help_kde; + State *_state; + +}; + + + + +class State : public KSystemTray { + Q_OBJECT +public: + State(); + ~State(); + + virtual void mousePressEvent(KSayItSystemTray *caller, QMouseEvent *e); + virtual void mouseReleaseEvent(KSayItSystemTray *caller, QMouseEvent *e); + virtual void setContext(KSayItSystemTray *caller); + +protected: + void changeState(KSayItSystemTray *caller, State *state); + void say(KSayItSystemTray *caller); + void mousePressEventCall(KSayItSystemTray *caller, QMouseEvent *e); + void mouseReleaseEventCall(KSayItSystemTray *caller, QMouseEvent *e); +}; + + + + +class StateWAIT : public State { + +public: + static StateWAIT* Instance(); + ~StateWAIT(); + +protected: + StateWAIT(); + void mousePressEvent(KSayItSystemTray *caller, QMouseEvent *e); + void mouseReleaseEvent(KSayItSystemTray *caller, QMouseEvent *e); + void setContext(KSayItSystemTray *caller); + +private: + static StateWAIT *_instance; + QPixmap m_traypixmap; +}; + + + + +class StateSAY : public State { + +public: + static StateSAY* Instance(); + ~StateSAY(); + +protected: + StateSAY(); + void mousePressEvent(KSayItSystemTray *caller, QMouseEvent *e); + void mouseReleaseEvent(KSayItSystemTray *caller, QMouseEvent *e); + void setContext(KSayItSystemTray *caller); + +private: + static StateSAY *_instance; + QPixmap m_traypixmap; +}; + + + + +class StateCLIPEMPTY : public State { + +public: + static StateCLIPEMPTY* Instance(); + ~StateCLIPEMPTY(); + +protected: + StateCLIPEMPTY(); + void mousePressEvent(KSayItSystemTray *caller, QMouseEvent *e); + void mouseReleaseEvent(KSayItSystemTray *caller, QMouseEvent *e); + void setContext(KSayItSystemTray *caller); + +private: + static StateCLIPEMPTY *_instance; + QPixmap m_traypixmap; +}; + + +#endif diff --git a/ksayit/src/ksayitui.rc b/ksayit/src/ksayitui.rc new file mode 100644 index 0000000..4352908 --- /dev/null +++ b/ksayit/src/ksayitui.rc @@ -0,0 +1,38 @@ +<!DOCTYPE kpartgui> +<kpartgui version="0.1" name="ksayit" > + <ActionProperties> + <Action icon="player_play" name="say_it" /> + <Action icon="player_pause" name="pause" /> + <Action icon="player_stop" name="shut_up" /> + <Action icon="2rightarrow" name="next_sentence" /> + <Action icon="2leftarrow" name="prev_sentence" /> + <Action icon="editdelete" name="clear" /> + <Action icon="edit" name="edittext" /> + </ActionProperties> + <MenuBar> + <Menu name="action" > + <text>&Action</text> + <Action name="prev_sentence" /> + <Action name="say_it" /> + <Action name="next_sentence" /> + <Action name="pause" /> + <Action name="shut_up" /> + <Separator lineSeparator="true" /> + <Action name="edittext" /> + <Action name="clear" /> + </Menu> + <Action name="bookmarks" /> + </MenuBar> + <ToolBar noMerge="1" name="mainToolBar" > + <text>Main Toolbar</text> + <Action name="bookmarks" /> + <Separator name="separator_1" /> + <Action name="prev_sentence" /> + <Action name="say_it" /> + <Action name="next_sentence" /> + <Action name="pause" /> + <Action name="shut_up" /> + <Separator name="separator_0" /> + <Action name="edittext" /> + </ToolBar> +</kpartgui> diff --git a/ksayit/src/ksayitviewimpl.cpp b/ksayit/src/ksayitviewimpl.cpp new file mode 100644 index 0000000..e619f8c --- /dev/null +++ b/ksayit/src/ksayitviewimpl.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + ksayitviewimpl.cpp - description + ------------------- + begin : Son Aug 10 2003 + copyright : (C) 2003 by Robert Vogl + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + + +#include <iostream> +using namespace std; + + // QT includes +#include <qradiobutton.h> +#include <qtextstream.h> +#include <qstring.h> + +// KDE includes +#include <kdebug.h> +#include <klocale.h> +#include <ktextedit.h> +#include <kmessagebox.h> + +// App specific includes +#include "ksayitviewimpl.h" + +KSayItViewImpl::KSayItViewImpl(QWidget *parent, const char *name ) : KSayItView(parent,name) { + + // some presets + +} +KSayItViewImpl::~KSayItViewImpl(){ +} + +QString& KSayItViewImpl::getText(){ + t = TextEdit->text(); + return t; +} + + +void KSayItViewImpl::enableTextedit( bool enable ) +{ + // if enable==true, we are in Edit Mode => RTF-Mode off. + if ( enable ){ + TextEdit->setTextFormat( Qt::PlainText); + } else { + TextEdit->setTextFormat( Qt::RichText); + } + TextEdit->setReadOnly( !enable ); +} + + +void KSayItViewImpl::slotTextChanged() +{ + int length = TextEdit->length(); + if ( length > 2 ){ + emit signalTextChanged(false); + } else { + emit signalTextChanged(true); + } +} + +void KSayItViewImpl::slotCopyAvailable(bool available) +{ + // enable/disable copy/cut-action in the menubar + if (available) + emit signalEnableCopyCut(true); + else + emit signalEnableCopyCut(false); +} + +void KSayItViewImpl::slotCopy() +{ + // copy selected text to the clipboard + TextEdit->copy(); +} + + +void KSayItViewImpl::slotCut() +{ + // copy selected text to the clipboard and delete it + TextEdit->cut(); +} + + +void KSayItViewImpl::slotPaste() +{ + // paste text from the clipboard to the texteditor + TextEdit->paste(); +} + +void KSayItViewImpl::textClear() +{ + // deletes the entire text of the texteditor + TextEdit->clear(); +} + +void KSayItViewImpl::setText(const QString &text) +{ + // set text to text + TextEdit->setText( text ); +} + + + +#include "ksayitviewimpl.moc" diff --git a/ksayit/src/ksayitviewimpl.h b/ksayit/src/ksayitviewimpl.h new file mode 100644 index 0000000..fea6c36 --- /dev/null +++ b/ksayit/src/ksayitviewimpl.h @@ -0,0 +1,97 @@ +/*************************************************************************** + ksayitviewimpl.h - description + ------------------- + begin : Son Aug 10 2003 + copyright : (C) 2003 by Robert Vogl + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef KSAYITVIEWIMPL_H +#define KSAYITVIEWIMPL_H + +// QT includes +#include <qwidget.h> +#include <qstring.h> + +// KDE includes + +// App includes +#include <KSayItView.h> + +/** + *@author Robert Vogl + */ + +class KSayItViewImpl : public KSayItView { + Q_OBJECT + +public: + KSayItViewImpl(QWidget *parent=0, const char *name=0); + ~KSayItViewImpl(); + +signals: + void signalSetCaption(const QString &caption); + void signalShowStatus(const QString &status); + void signalEnableCopyCut(bool enable); + + /** Emitted when the text in the TextEditor view cahnges. + * \param empty True if the TextEditor view is empty. + */ + void signalTextChanged(bool empty); + +public slots: + /** True if text is selected or false if text is deselected. + */ + void slotCopyAvailable(bool available); + + /** Copy selected text to the clipboard. + */ + void slotCopy(); + + /** Copy selected text to the clipboard and delete it. + */ + void slotCut(); + + /** Paste text from the clipboard to the texteditor. + */ + void slotPaste(); + +private slots: + /** Called from the widget + */ + void slotTextChanged(); + +public: // Methods + /** Returns the text of the TextEdit-Widget + */ + QString& getText(); + + /** Set the content of the textEdit-Widget to text + */ + void setText(const QString &text); + + /** Enables/disables the Textedit + * \param enable true=enabled, false=diabled + */ + void enableTextedit( bool enable ); + + /** Deletes the entire text of the texteditor. + */ + void textClear(); + +private: + QString t; + + +}; + +#endif diff --git a/ksayit/src/main.cpp b/ksayit/src/main.cpp new file mode 100644 index 0000000..9dcf0fe --- /dev/null +++ b/ksayit/src/main.cpp @@ -0,0 +1,62 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Son Aug 10 13:26:57 EDT 2003 + copyright : (C) 2003 by Robert Vogl + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <stdlib.h> + +// QT includes + +// KDE includes +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <kaboutdata.h> +#include <kglobal.h> +#include <klocale.h> +#include <arts/kartsdispatcher.h> +#include <dcopclient.h> + +// App specific includes +#include "version.h" +#include "ksayit.h" + +static const char *description = + I18N_NOOP("KSayIt - A Text To Speech frontend for KDE"); +// INSERT A DESCRIPTION FOR YOUR APPLICATION HERE + + +int main(int argc, char *argv[]) +{ + + KAboutData aboutData( "ksayit", I18N_NOOP("KSayIt"), + KSAYIT_VERSION, description, KAboutData::License_GPL, + "(c) 1996 - 2005, Robert Vogl", 0, 0, "voglrobe@web.de"); + aboutData.addAuthor("Robert Vogl",0, "voglrobe@web.de"); + KCmdLineArgs::init( argc, argv, &aboutData ); + + KApplication app; + + // setup MCOP + KArtsDispatcher dispatcher; + + // setup DCOP + QCString appID = app.dcopClient()->registerAs( app.name(), false ); + + KSayItApp *ksayit = new KSayItApp(0, "MainWindow", 0, appID); + // ksayit->hide(); + ksayit->show(); + + return app.exec(); +} diff --git a/ksayit/src/parasaxparser.cpp b/ksayit/src/parasaxparser.cpp new file mode 100644 index 0000000..575df06 --- /dev/null +++ b/ksayit/src/parasaxparser.cpp @@ -0,0 +1,96 @@ +// +// C++ Implementation: parasaxparser +// +// Description: SAX2-Parser for 'para' elements of a DocBook file. +// +// +// Author: Robert Vogl <voglrobe@web.de>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// +// #include <iostream> // cout +// using namespace std; + +// Qt includes + +// KDE includes +#include <kdebug.h> + +// App specific includes +#include "parasaxparser.h" + +ParaSaxParser::ParaSaxParser() +{ + m_reader = new QXmlSimpleReader(); + + m_handler = new SaxHandler(); + m_reader->setContentHandler(m_handler); + m_reader->setErrorHandler(m_handler); + m_reader->setEntityResolver(m_handler); + m_reader->setDeclHandler(m_handler); + + m_XmlInputHeader = QString::null; + m_XmlInputBody = QString::null; +} + +ParaSaxParser::~ParaSaxParser() +{ + delete m_handler; + delete m_reader; +} + +ParaSaxParser* ParaSaxParser::_instance = 0; + +ParaSaxParser* ParaSaxParser::Instance() +{ + if ( _instance == 0 ){ + _instance = new ParaSaxParser(); + } + return _instance; +} + + +void ParaSaxParser::setProcessingInstruction(const QString &data) +{ + m_XmlInputHeader = data; +} + + +void ParaSaxParser::setData(const QString &data) +{ + m_XmlInputBody = data; +} + + +void ParaSaxParser::getText(QString &data) +{ + QString XmlPart = m_XmlInputHeader + m_XmlInputBody; + + QXmlInputSource input; + input.setData(XmlPart); + + m_handler->reset(); + m_handler->setRTF(false); + m_reader->parse( input ); + m_handler->getData(data); + +} + + +void ParaSaxParser::getRTFText(QString &data) +{ + QString XmlPart = m_XmlInputHeader + m_XmlInputBody; + kdDebug(100200) << "ParaSaxParser::getRTFText(): " << XmlPart << endl; + + QXmlInputSource input; + input.setData(XmlPart); + + m_handler->reset(); + m_handler->setRTF(true); + m_reader->parse( input ); + m_handler->getData(data); +} + + + diff --git a/ksayit/src/parasaxparser.h b/ksayit/src/parasaxparser.h new file mode 100644 index 0000000..e76d652 --- /dev/null +++ b/ksayit/src/parasaxparser.h @@ -0,0 +1,77 @@ +// +// C++ Interface: parasaxparser +// +// Description: SAX2-Parser for 'para' elements of a DocBook file. +// +// +// Author: Robert Vogl <voglrobe@web.de>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef PARASAXPARSER_H +#define PARASAXPARSER_H + +// Qt includes +#include <qxml.h> +#include <qstring.h> + +// App specific includes +#include "saxhandler.h" + +/** +This class is a singleton. +@author Robert Vogl +*/ +class ParaSaxParser{ +public: + ~ParaSaxParser(); + + /** + * Creates the single instance of this parser (if not + * allready exists) and returns a pointer to it. + */ + static ParaSaxParser* Instance(); + + /** + * Because this parser sees nothing but the 'para' + * parts of the document, it requires the documents header + * info, e.g. to resolve entities defined in the internal DTD. + * \param data The header (preamble) of the DocBook document. + */ + void setProcessingInstruction(const QString &data); + + /** + * This is the 'para' element to parse. It has to be encapsulated + * in <para> and </para>. Nested 'para' elements are not supported. + * \param data See description. + */ + void setData(const QString &data); + + /** + * Returns the pure text content of the paragraph without tags. + * \param data See description. + */ + void getText(QString &data); + + /** + * Returns the text in RTF format, i.e. replaces DocBook tags + * with RTF tags. + * \param data See description. + */ + void getRTFText(QString &data); + +protected: + ParaSaxParser(); + +private: + static ParaSaxParser* _instance; + SaxHandler* m_handler; + QXmlSimpleReader* m_reader; + QString m_XmlInputHeader; + QString m_XmlInputBody; + + +}; + +#endif diff --git a/ksayit/src/saxhandler.cpp b/ksayit/src/saxhandler.cpp new file mode 100644 index 0000000..2f8d49c --- /dev/null +++ b/ksayit/src/saxhandler.cpp @@ -0,0 +1,187 @@ +// +// C++ Implementation: saxhandler +// +// Description: +// +// +// Author: Robert Vogl <voglrobe@web.de>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// +// #include <iostream> // cout +// using namespace std; + +// KDE includes +#include <kdebug.h> +#include <klocale.h> +#include <kmessagebox.h> + +// App specific includes +#include "saxhandler.h" + +SaxHandler::SaxHandler() + : QXmlDefaultHandler() +{ + m_output = QString::null; + m_rtf = true; + m_tagmap["action"] = "B"; + m_tagmap["application"] = "B"; + m_tagmap["function"] = "B"; + m_tagmap["guibutton"] = "B"; + m_tagmap["guiicon"] = "B"; + m_tagmap["guilabel"] = "B"; + m_tagmap["guimenu"] = "B"; + m_tagmap["guimenuitem"] = "B"; + m_tagmap["guisubmenu"] = "B"; + m_tagmap["menuchoice"] = "B"; + m_tagmap["mousebutton"] = "B"; + m_tagmap["option"] = "B"; + m_tagmap["author"] = "B"; + m_tagmap["corpauthor"] = "B"; + m_tagmap["warning"] = "FONT color=\"red\""; + m_tagmap["command"] = "TT"; + m_tagmap["email"] = "TT"; + m_tagmap["filename"] = "TT"; + m_tagmap["keycap"] = "TT"; + m_tagmap["keycode"] = "TT"; + m_tagmap["keycombo"] = "TT"; + m_tagmap["keysym"] = "TT"; + m_tagmap["link"] = "TT"; + m_tagmap["literal"] = "TT"; + m_tagmap["userinput"] = "TT"; + m_tagmap["citation"] = "EM"; + m_tagmap["emphasis"] = "EM"; + m_tagmap["foreignphrase"] = "EM"; + m_tagmap["phrase"] = "EM"; + m_tagmap["comment"] = "EM"; + m_tagmap["note"] = "EM"; + m_tagmap["tip"] = "EM"; + m_tagmap["subscript"] = "small"; + m_tagmap["superscript"] = "small"; + m_tagmap["itemizedlist"] = "UL"; + m_tagmap["listitem"] = "LI"; +} + +SaxHandler::~SaxHandler() +{ +} + + +void SaxHandler::setRTF(bool rtf) +{ + m_rtf = rtf; +} + + +bool SaxHandler::startElement(const QString &, + const QString &, + const QString & qName, + const QXmlAttributes & atts ) +{ + if ( !m_rtf ) + return true; + + QString tag = qName.lower(); + + TagMapT::iterator it; + it = m_tagmap.find(tag); + if ( it != m_tagmap.end() ){ + // tag found in hash table + QString rtftag = (*it).second; + m_output += "<" + rtftag + ">"; + } + + return true; +} + + +bool SaxHandler::endElement(const QString &, + const QString &, + const QString & qName) +{ + if ( !m_rtf ) + return true; + + QString tag = qName.lower(); + + TagMapT::iterator it; + it = m_tagmap.find(tag); + if ( it != m_tagmap.end() ){ + // tag found in hash table + QString rtftag = (*it).second; + m_output += "</" + rtftag.section(" ", 0, 0) + ">"; + } + + return true; +} + + +bool SaxHandler::characters(const QString & ch) +{ + m_output += ch; + return true; +} + + +bool SaxHandler::fatalError(const QXmlParseException &exc) +{ + QString err = i18n("Fatal error while parsing XML-Paragraph:\n"); + err += i18n("%1, Line: %2").arg(exc.message()).arg(exc.lineNumber()); + KMessageBox::error(0, err, i18n("Fatal error") ); + return false; +} + + +bool SaxHandler::resolveEntity(const QString &publicId, + const QString &systemId, + QXmlInputSource* &ret) +{ + return true; +} + + +bool SaxHandler::externalEntityDecl(const QString & name, + const QString & publicId, + const QString & systemId) +{ + kdDebug(100200) << "externalEntityDecl(): " << name << ", " << publicId << ", " << systemId << endl; + return true; +} + + +bool SaxHandler::internalEntityDecl(const QString & name, + const QString & value) +{ + kdDebug() << "internalEntityDecl(): " << name << ", " << value << endl; + return true; +} + + +bool SaxHandler::skippedEntity(const QString &name) +{ + QString warn = i18n("Unresolved entity found: %1.\n").arg(name); + warn += i18n("KSayIt does not support DocBook files with external entities. "); + warn += i18n("Parsing can continue, but the resulting text will contain gaps."); + + int res; + // TODO: "Option: don't show again this warning." + res = KMessageBox::warningContinueCancel(0, warn, i18n("Parser problem") ); + if ( res == KMessageBox::Cancel ) + return false; + return true; +} + + +void SaxHandler::getData( QString &data ) const +{ + data = m_output; +} + + +void SaxHandler::reset() +{ + m_output = QString::null; +} + + diff --git a/ksayit/src/saxhandler.h b/ksayit/src/saxhandler.h new file mode 100644 index 0000000..45061f3 --- /dev/null +++ b/ksayit/src/saxhandler.h @@ -0,0 +1,87 @@ +// +// C++ Interface: saxhandler +// +// Description: Qt SAX2-Handler +// +// +// Author: Robert Vogl <voglrobe@web.de>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef SAXHANDLER_H +#define SAXHANDLER_H + +// STL includes +#include <map> +using namespace std; + +// Qt includes +#include <qxml.h> +#include <qstring.h> + +typedef map<QString, QString> TagMapT; + + +/** +@author Robert Vogl +*/ +class SaxHandler : public QXmlDefaultHandler +{ +public: + SaxHandler(); + ~SaxHandler(); + + // Reimplementations from base class + bool startElement(const QString &namespaceURI, + const QString &localName, + const QString &qName, + const QXmlAttributes &atts ); + + bool endElement(const QString &namespaceURI, + const QString &localName, + const QString &qName); + + bool characters(const QString &ch); + + bool fatalError(const QXmlParseException &exc); + + bool resolveEntity(const QString &publicId, + const QString &systemId, + QXmlInputSource* &ret); + + bool externalEntityDecl(const QString &name, + const QString &publicId, + const QString &systemId); + + bool internalEntityDecl(const QString &name, + const QString &value); + + bool skippedEntity(const QString &name); + + /** + * Returns the parser result. + */ + void getData( QString &data ) const; + + /** + * Reset + */ + void reset(); + + /** + * Set Mode: + * \param rtf 'true' = Replace DocBook tags with RTF-tags.\n + * 'false' = Ignore tags, return text content only. + */ + void setRTF(bool rtf); + + +private: + QString m_output; + bool m_rtf; + TagMapT m_tagmap; + +}; + +#endif diff --git a/ksayit/src/version.h b/ksayit/src/version.h new file mode 100644 index 0000000..180c99f --- /dev/null +++ b/ksayit/src/version.h @@ -0,0 +1,23 @@ +/*************************************************************************** + version.h - description + ------------------- + begin : Son Aug 10 13:26:57 EDT 2003 + copyright : (C) 2003 by Robert Vogl + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef VERSION_H +#define VERSION_H + +const char* KSAYIT_VERSION = " 0.8.4"; + +#endif // VERSION_H diff --git a/ksayit/src/voicesetupdlg.cpp b/ksayit/src/voicesetupdlg.cpp new file mode 100644 index 0000000..bdf6db3 --- /dev/null +++ b/ksayit/src/voicesetupdlg.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** + voicesetupdlg.cpp - description + ------------------- + begin : Son Nov 2 2003 + copyright : (C) 2003 by Robert Vogl + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +// #include <iostream> +// using namespace std; + +// QT includes +#include <qpixmap.h> +#include <qstringlist.h> +#include <qcombobox.h> +#include <qcolor.h> +#include <qlayout.h> +#include <qwidget.h> + +// KDE includes +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kmessagebox.h> + +// App specific includes +#include "voicesetupdlg.h" +#include "fxsetupimpl.h" +#include "fxpluginhandler.h" +#include "kttsdlib.h" + +VoiceSetupDlg::VoiceSetupDlg(QWidget *parent, const char *name, const QString &caption, + bool modal, + KConfig *config, + FXPluginHandler *fxpluginhandler, + KTTSDLib *ttslib) + : KDialogBase(IconList, caption, Ok|Cancel, Ok, parent, name, modal, true), + m_config(config), + m_fxpluginhandler(fxpluginhandler), + m_kttslib(ttslib) +{ + + setIconListAllVisible(true); + connect (this, SIGNAL(aboutToShowPage(QWidget*)), this, SLOT(slotPageChanged(QWidget*))); + + initVoicePage(); + initFXPage(); + +} + + +VoiceSetupDlg::~VoiceSetupDlg() +{ +} + + +void VoiceSetupDlg::initVoicePage() +{ + QPixmap icon = KGlobal::iconLoader()->loadIcon("ksayit", KIcon::Toolbar, KIcon::SizeMedium); + QFrame *voicePage = addPage( i18n( "Voice" ), i18n("Voice Settings"), icon ); + QVBoxLayout *voiceLayout = new QVBoxLayout( voicePage, 0, spacingHint() ); + + const QWidget *voiceDialog = m_kttslib->getGUI( voicePage ); + voiceLayout->addWidget( const_cast<QWidget*>(voiceDialog) ); +} + + +void VoiceSetupDlg::initFXPage() +{ + QPixmap icon = KGlobal::iconLoader()->loadIcon("ksysguard", KIcon::Toolbar, KIcon::SizeMedium); + m_fxPage = addPage( i18n( "Audio FX" ), i18n("Effect Stack"), icon ); + QVBoxLayout *fxLayout = new QVBoxLayout( m_fxPage, 0, spacingHint() ); + + FX_SetupImpl *fxDialog = new FX_SetupImpl(m_fxPage, "fxsetup", m_config, m_fxpluginhandler); + fxLayout->addWidget(fxDialog); + connect( this, SIGNAL(signalOKWasClicked()), fxDialog, SLOT(slotSaveWasClicked()) ); + connect( this, SIGNAL(signalRemoveAllFX()), fxDialog, SLOT(slotRemoveAll()) ); + connect( this, SIGNAL(signalReloadFX()), fxDialog, SLOT(slotReload()) ); + + // Disable/enable FX-Setup depending on TTS-libs capability + int status = m_kttslib->getStatus() & TTS::AUDIOFILE; + if ( status ){ + m_fxPage->setEnabled(true); + } else { + m_fxPage->setEnabled(false); + emit signalRemoveAllFX(); + } +} + + +void VoiceSetupDlg::slotPageChanged(QWidget *page) +{ + kdDebug(100200) << "+++ entering VoiceSetupDlg::slotPageChanged: " << page << endl; + + if ( page != m_fxPage ) + return; + + int status = m_kttslib->getStatus() & TTS::AUDIOFILE; + if ( status ){ + m_fxPage->setEnabled(true); + } else { + QString q = i18n("The active TTS system does not make use of aRts effects."); + KMessageBox::information( this, q, i18n("Plugin Configuration"), "KSayIt_Audiofile" ); + m_fxPage->setEnabled(false); + } +} + + +void VoiceSetupDlg::slotOk() +{ + kdDebug(100200) << "+++ entering VoiceSetupDlg::slotOK()" << endl; + + int status = m_kttslib->getStatus(); + if ( (status & TTS::AUDIOFILE) == 0 ){ + emit signalRemoveAllFX(); + } + + // Let all objects save their configuration + emit signalOKWasClicked(); + + // check if configuration was saved O.K. + if ( m_kttslib->saveWasClicked() ){ + kdDebug(100200) << "--- leaving VoiceSetupDlg::slotOk" << endl; + QDialog::accept(); + } +} + + +void VoiceSetupDlg::slotCancel() +{ + kdDebug(100200) << "VoiceSetupDlg::slotCancel()" << endl; + QDialog::reject(); +} + +#include "voicesetupdlg.moc" diff --git a/ksayit/src/voicesetupdlg.h b/ksayit/src/voicesetupdlg.h new file mode 100644 index 0000000..510c591 --- /dev/null +++ b/ksayit/src/voicesetupdlg.h @@ -0,0 +1,90 @@ +/*************************************************************************** + voicesetupdlg.h - description + ------------------- + begin : Son Nov 2 2003 + copyright : (C) 2003 by Robert Vogl + email : voglrobe@saphir + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef VOICESETUPDLG_H +#define VOICESETUPDLG_H + +// QT includes +#include <qframe.h> + +// KDE includes +#include <kdialogbase.h> +#include <kconfig.h> + +// forward declaration +class FXPluginHandler; +class KTTSDLib; +/** + *@author Robert Vogl + */ +class VoiceSetupDlg : public KDialogBase { + Q_OBJECT + +public: + VoiceSetupDlg(QWidget *parent=0, const char *name=0, const QString &caption=NULL, + bool modal=true, + KConfig *config=0, + FXPluginHandler *fxpluginhandler=0, + KTTSDLib *kttslib=0); + + ~VoiceSetupDlg(); + +signals: + /** Emitted when OK was cliecked; + */ + void signalOKWasClicked(); + + /** Signals to remove all effects from the active list. + */ + void signalRemoveAllFX(); + + /** Signals to relaod the last saved state. + */ + void signalReloadFX(); + +private: // Methods + /** Initializes the configuration page to setup the properties of + * of the TTS system. + */ + void initVoicePage(); + + /** Initializes the configuration page to setup the effects. + */ + void initFXPage(); + +private slots: + /** Called when the Page changes. + */ + void slotPageChanged(QWidget *page); + + /** Reimplementation from base class. + */ + void slotCancel(); + + /** Reimplementation from base class. + */ + void slotOk(); + +private: + KConfig *m_config; + FXPluginHandler *m_fxpluginhandler; + KTTSDLib *m_kttslib; + QFrame *m_fxPage; + +}; + +#endif |