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 | e9ae80694875f869892f13f4fcaf1170a00dea41 (patch) | |
| tree | aa2f8d8a217e2d376224c8d46b7397b68d35de2d /quanta/src/quantaview.cpp | |
| download | tdewebdev-e9ae80694875f869892f13f4fcaf1170a00dea41.tar.gz tdewebdev-e9ae80694875f869892f13f4fcaf1170a00dea41.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/kdewebdev@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'quanta/src/quantaview.cpp')
| -rw-r--r-- | quanta/src/quantaview.cpp | 1185 | 
1 files changed, 1185 insertions, 0 deletions
| diff --git a/quanta/src/quantaview.cpp b/quanta/src/quantaview.cpp new file mode 100644 index 00000000..39cff3bc --- /dev/null +++ b/quanta/src/quantaview.cpp @@ -0,0 +1,1185 @@ +/*************************************************************************** +                          quantaview.cpp  -  description +                             ------------------- +    begin                : ���� 9 13:29:57 EEST 2000 +    copyright            : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <pdima@users.sourceforge.net,yshurik@linuxfan.com,sequitur@easystreet.com> +                           (C) 2001-2005 Andras Mantia <amantia@kde.org> + ***************************************************************************/ + +/*************************************************************************** + *                                                                         * + *   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 files for Qt +#include <qprinter.h> +#include <qpainter.h> +#include <qtabbar.h> +#include <qtabwidget.h> +#include <qtimer.h> +#include <qlayout.h> +#include <qwidgetstack.h> +#include <qdom.h> +#include <qfile.h> +#include <qevent.h> +#include <qwidget.h> +#include <qsplitter.h> +#include <qpoint.h> +#include <qscrollview.h> + +// include files for KDE +#include <kaction.h> +#include <kdebug.h> +#include <kdirwatch.h> +#include <khtmlview.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kmenubar.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kurldrag.h> +#include <kdeversion.h> +#include <kparts/partmanager.h> +#include <kstatusbar.h> + +#include "undoredo.h" +#include "kafkacommon.h" +#include "wkafkapart.h" + +#include <ktexteditor/document.h> +#include <ktexteditor/selectioninterface.h> +#include <ktexteditor/selectioninterfaceext.h> +#include <ktexteditor/view.h> +#include <ktexteditor/viewcursorinterface.h> + +// application specific includes +#include "document.h" +#include "resource.h" +#include "quantaview.h" +#include "quanta.h" +#include "quantacommon.h" +#include "qextfileinfo.h" +#include "viewmanager.h" + +#include "tagaction.h" +#include "toolbartabwidget.h" +#include "quantaplugin.h" +#include "project.h" +#include "structtreeview.h" + +#include "tagdialog.h" + +extern int NN; +extern QValueList<Node*> nodes; + +QuantaView::QuantaView(QWidget *parent, const char *name, const QString &caption ) +  : KMdiChildView(parent, name) +  , m_document(0L) +  , m_plugin(0L) +  , m_customWidget(0L) +  , m_kafkaDocument(0L) +  , m_currentFocus(SourceFocus) +{ +  setMDICaption(caption); +//Connect the VPL update timers +  connect(&m_sourceUpdateTimer, SIGNAL(timeout()), this, SLOT(sourceUpdateTimerTimeout())); +  connect(&m_VPLUpdateTimer, SIGNAL(timeout()), this, SLOT(VPLUpdateTimerTimeout())); + +//create the source and VPL holding widgets +  m_documentArea = new QWidget(this); + +//get the reference to the user toolbar holding widget +  ToolbarTabWidget *m_toolbarTab = ToolbarTabWidget::ref(); +  m_toolbarTab->reparent(this, 0, QPoint(), true); +  m_toolbarTab ->setFocusPolicy( QWidget::NoFocus ); + +//create a splitter to separate the VPL and document area +  m_splitter = new QSplitter(Qt::Vertical, this); +//place the widgets in a grid +  m_viewLayout = new QGridLayout(this, 2, 0); +  m_viewLayout->setRowStretch(0, 0); +  m_viewLayout->setRowStretch(1,1); +  m_viewLayout->addWidget( m_toolbarTab, 0, 0); +  m_viewLayout->addWidget( m_documentArea, 1, 0); + +  m_documentArea->show(); + +  setAcceptDrops(true); // [MB02] Accept drops on the view +} + +QuantaView::~QuantaView() +{ +   // quantaApp is undefined if the destructor of QuantaApp is active +   if (quantaApp) +     quantaApp->slotFileClosed(m_document); +   if (m_document) +   { +     m_document->view()->reparent(0L, 0, QPoint(), false); +     if (quantaApp) +       emit documentClosed(m_document->url()); +   } +   delete m_document; +   m_document = 0L; +} + +bool QuantaView::mayRemove() +{ +  emit hidePreview(); +  if (m_plugin) +  { +    m_plugin->unload(false); +  } else +  { +    bool unmodifiedUntitled = false; +    if (m_document && m_document->isUntitled() && !m_document->isModified()) +      unmodifiedUntitled = true; +    if (m_customWidget) +        m_customWidget->reparent(0L, 0, QPoint(), false); +    if (!saveModified()) +          return false; +    slotSetSourceLayout(); +    if (static_cast<QuantaView *>(quantaApp->activeWindow()) == this) +    { +        parser->setSAParserEnabled(false); +        kdDebug(24000) << "Node objects before delete = " << NN << " ; list count = " << nodes.count() << endl; +        Node::deleteNode(baseNode); +        baseNode = 0L; +        kdDebug(24000) << "Node objects after delete = " << NN << " ; list count = " << nodes.count() << endl; +        QValueList<Node*> nList = nodes; +/*        for (QValueList<Node*>::ConstIterator it = nList.constBegin(); it != nList.constEnd(); ++it) +        Node::deleteNode(*it); +        kdDebug(24000) << "Node objects after cleanup = " << NN << " ; list count = " << nodes.count() << endl;*/ +    } +    if (m_document) +    { +      KURL url = m_document->url(); +      Project::ref()->saveBookmarks(url, dynamic_cast<KTextEditor::MarkInterface*>(m_document->doc())); +      if (!unmodifiedUntitled) +        emit eventHappened("before_close", url.url(), QString::null); +      m_currentViewsLayout = -1; +//      m_document->closeTempFile(); +      if (!m_document->isUntitled() && url.isLocalFile()) +      { +        fileWatcher->removeFile(url.path()); +//        kdDebug(24000) << "removeFile[mayRemove]: " << url.path() << endl; +      } +      Project::ref()->saveCursorPosition(url, dynamic_cast<KTextEditor::ViewCursorInterface*>(m_document->view())); + +      quantaApp->menuBar()->activateItemAt(-1); +      quantaApp->guiFactory()->removeClient(m_document->view()); +      if (!unmodifiedUntitled) +        emit eventHappened("after_close", url.url(), QString::null); +    } +/*      kdDebug(24000) << "Calling reparse from close " << endl; +      parser->setSAParserEnabled(true); +      quantaApp->reparse(true);*/ +  } +  return true; +} + +void QuantaView::addDocument(Document *document) +{ +   if (!document) +     return; +   m_document = document; +   connect(m_document, SIGNAL(editorGotFocus()), this, SLOT(slotSourceGetFocus())); +   connect(m_document->view(), SIGNAL(cursorPositionChanged()), this, SIGNAL(cursorPositionChanged())); + + +   m_kafkaDocument = KafkaDocument::ref(); + +  connect(m_kafkaDocument->getKafkaWidget(), SIGNAL(hasFocus(bool)), +    this, SLOT(slotVPLGetFocus(bool))); +  connect(m_kafkaDocument, SIGNAL(newCursorPosition(int,int)), +    this, SLOT(slotSetCursorPositionInSource(int, int))); +  connect(m_kafkaDocument, SIGNAL(loadingError(Node *)), +    this, SLOT(slotVPLLoadingError(Node *))); + +   m_kafkaReloadingEnabled = true; +   m_quantaReloadingEnabled = true; +   m_curCol = m_curLine = m_curOffset = 0; + +//init the VPL part +  m_currentViewsLayout = SourceOnly;//to correctly reload the timers. + +  reloadUpdateTimers(); + +   m_currentViewsLayout = -1; //force loading of this layout +   slotSetSourceLayout(); +} + +void QuantaView::addPlugin(QuantaPlugin *plugin) +{ +   ToolbarTabWidget *m_toolbarTab = ToolbarTabWidget::ref(); +   m_toolbarTab->reparent(0, 0, QPoint(), false); +   m_plugin = plugin; +   m_splitter->hide(); +   QWidget *w = m_plugin->widget(); +   if (w) +   { +       w->reparent(m_documentArea, 0, QPoint(), true); +       w->resize(m_documentArea->size()); +   } +   m_documentArea->reparent(this, 0, QPoint(), true); +   m_viewLayout->addWidget(m_documentArea, 1, 0); +   activated(); +   updateTab(); +} + +void QuantaView::addCustomWidget(QWidget *widget, const QString &label) +{ +   if (widget) +   { +      ToolbarTabWidget::ref()->reparent(0, 0, QPoint(), false); +      m_customWidget = widget; +      m_splitter->hide(); +      widget->reparent(m_documentArea, 0, QPoint(), true); +      widget->resize(m_documentArea->size()); +      if (!label.isEmpty()) +      { +          widget->setCaption(label); +          updateTab(); +      } +      m_viewLayout->addWidget(m_documentArea, 1, 0); +      m_documentArea->show(); +   } else +   if (m_customWidget) +   { +      ToolbarTabWidget::ref()->reparent(this, 0, QPoint(), qConfig.enableDTDToolbar); +      m_viewLayout->addWidget(ToolbarTabWidget::ref(), 0 , 0); +      m_customWidget = 0L; //avoid infinite recursion +      reloadLayout(); +   } +  if (m_documentArea->height() + ToolbarTabWidget::ref()->height() > height() && ToolbarTabWidget::ref()->isVisible()) +    resize(m_documentArea->width(), m_documentArea->height() - ToolbarTabWidget::ref()->height()); +  else if (ToolbarTabWidget::ref()->isHidden()) +    resize(width(), height()); +} + +void QuantaView::reloadLayout() +{ +  int currentViewsLayout = m_currentViewsLayout; +  m_currentViewsLayout = -1; //force loading of this layout +  switch (currentViewsLayout) +  { +        case SourceOnly: +            slotSetSourceLayout(); +            break; +        case SourceAndVPL: +            slotSetSourceAndVPLLayout(); +            break; +        case VPLOnly: +            slotSetVPLOnlyLayout(); +            break; +  } +} + +void QuantaView::updateTab() +{ +    if (qConfig.showCloseButtons == "ShowAlways") +    { +        setIcon(SmallIcon("fileclose")); +    } +    if (m_document) +    { +        // try to set the icon from mimetype +        QIconSet mimeIcon (KMimeType::pixmapForURL(m_document->url(), 0, KIcon::Small)); +        if (mimeIcon.isNull()) +          mimeIcon = QIconSet(SmallIcon("document")); +        QString urlStr = QExtFileInfo::shortName(m_document->url().path()); +        if (m_document->isModified()) +        { +            if (qConfig.showCloseButtons == "ShowAlways") +            { +               setMDICaption(urlStr + " " + i18n("[modified]")); +            } else +            { +                setIcon(SmallIcon("filesave")); +                setMDICaption(urlStr); +            } +            m_szCaption = urlStr + " " + i18n("[modified]"); +        } else +        { +          if (qConfig.showCloseButtons != "ShowAlways") +          { +             setIcon(mimeIcon.pixmap()); +          } +          setMDICaption(urlStr); +          quantaApp->setTabToolTip(this, m_document->url().prettyURL(0, KURL::StripFileProtocol)); +        } +    } else +    if (m_plugin) +    { +        if (qConfig.showCloseButtons != "ShowAlways") +        { +            setIcon(SmallIcon(m_plugin->icon())); +        } +       setMDICaption(m_plugin->name()); +    } else +    if (m_customWidget) +    { +        if (qConfig.showCloseButtons != "ShowAlways") +        { +            setIcon(*(m_customWidget->icon())); +        } +        setMDICaption(m_customWidget->caption()); +    } +} + +QString QuantaView::tabName() +{ +   if (m_document) +   { +       return m_document->url().fileName(); +   } else +   if (m_plugin) +   { +       return m_plugin->name(); +   } else +   if (m_customWidget) +   { +       return m_customWidget->caption(); +   } else +   return ""; +} + +void QuantaView::slotSetSourceLayout() +{ +   emit hidePreview(); +   if (m_currentViewsLayout == SourceOnly || !m_document) +     return; + +   if(m_currentViewsLayout == SourceAndVPL) +     m_splitterSizes = m_splitter->sizes(); + +   KToggleAction *ta = (KToggleAction *) quantaApp->actionCollection()->action( "show_quanta_editor" ); +   if (ta) +      ta->setChecked(true); + +   //hide the VPL widget, reload the source if necessary +   if ((m_currentViewsLayout == SourceAndVPL && m_kafkaDocument->getKafkaWidget()->view()->hasFocus()) || +     m_currentViewsLayout == VPLOnly) +   { +          reloadSourceView(); +   } +   if (m_kafkaDocument->isLoaded()) +       m_kafkaDocument->unloadDocument(); + +//show the document if full size +   m_splitter->hide(); +   m_kafkaDocument->getKafkaWidget()->view()->reparent(0, 0, QPoint(), false); +   m_document->view()->reparent(m_documentArea, 0, QPoint(), true); +   m_document->view()->resize(m_documentArea->size()); +   m_viewLayout->addWidget(m_documentArea, 1, 0); +   m_document->view()->setFocus(); + +   m_currentViewsLayout = SourceOnly; + +//update timers are not needed in source only mode +   m_sourceUpdateTimer.stop(); +   m_VPLUpdateTimer.stop(); +} + + +void QuantaView::slotSetSourceAndVPLLayout() +{ +   emit hidePreview(); +   if (m_currentViewsLayout == SourceAndVPL  || !m_document) +     return; + +   KToggleAction *ta = (KToggleAction *) quantaApp->actionCollection()->action( "show_kafka_and_quanta" ); + +   if (m_document->defaultDTD()->name.contains("HTML", false) == 0) +   { +      KMessageBox::information(this, i18n("The VPL Mode does not support the current DTD, at the moment: %1").arg(m_document->defaultDTD()->nickName)); +      KToggleAction *ta2 = (KToggleAction *) quantaApp->actionCollection()->action( "show_quanta_editor" ); +      if (ta2) +          ta2->setChecked(true); +      return; +  } + +   if (ta) +       ta->setChecked(true); + + +    if (!m_kafkaDocument->isLoaded()) +        m_kafkaDocument->loadDocument(m_document); +    if (m_currentViewsLayout == VPLOnly) +    { +      reloadSourceView(); +    } +    m_kafkaDocument->getKafkaWidget()->view()->reparent(m_splitter, 0, QPoint(), true); +    m_splitter->moveToFirst(m_kafkaDocument->getKafkaWidget()->view()); +    m_document->view()->reparent(m_splitter, 0, QPoint(), true); +    m_viewLayout->addWidget(m_splitter, 1, 0); +    m_splitter->setSizes(m_splitterSizes); +    m_splitter->show(); + +    if ( m_currentViewsLayout == SourceOnly && +         (!baseNode || (baseNode->tag->type == Tag::Empty && +          !baseNode->next && !baseNode->child))) +    { +        quantaApp->documentProperties(true); +    } + +   m_currentViewsLayout = SourceAndVPL; + +   reloadUpdateTimers(); +} + +void QuantaView::slotSetVPLOnlyLayout() +{ +   emit hidePreview(); +   if (m_currentViewsLayout == VPLOnly || !m_document) +     return; + +   if(m_currentViewsLayout == SourceAndVPL) +     m_splitterSizes = m_splitter->sizes(); + +   KToggleAction *ta = (KToggleAction *) quantaApp->actionCollection()->action( "show_kafka_view" ); + +   if (m_document->defaultDTD()->name.contains("HTML", false) == 0) +   { +      KMessageBox::information(this, i18n("The VPL Mode does not support the current DTD, at the moment: %1").arg(m_document->defaultDTD()->nickName)); +      KToggleAction *ta2 = (KToggleAction *) quantaApp->actionCollection()->action( "show_quanta_editor" ); +      if (ta2) +          ta2->setChecked(true); +      return; +  } + +   if (ta) +       ta->setChecked(true); + +   m_splitter->hide(); +   if (!m_kafkaDocument->isLoaded()) +        m_kafkaDocument->loadDocument(m_document); + +   m_kafkaDocument->getKafkaWidget()->view()->reparent(m_documentArea, 0, QPoint(), true); +   m_kafkaDocument->getKafkaWidget()->view()->resize(m_documentArea->size()); +   m_viewLayout->addWidget(m_documentArea, 1, 0); +   m_kafkaDocument->getKafkaWidget()->view()->setFocus(); + +   if ( m_currentViewsLayout == SourceOnly && +         (!baseNode || (baseNode->tag->type == Tag::Empty && +          !baseNode->next && !baseNode->child))) +   { +      quantaApp->documentProperties(true); +   } + +   m_currentViewsLayout = VPLOnly; + + +//update timers are not needed in VPL only mode +    m_sourceUpdateTimer.stop(); +    m_VPLUpdateTimer.stop(); +} + +void QuantaView::reloadUpdateTimers() +{ +    QuantaView* view=ViewManager::ref()->activeView(); + +    m_sourceUpdateTimer.stop(); +    m_VPLUpdateTimer.stop(); + +   if (m_kafkaDocument->isLoaded() && m_currentViewsLayout == SourceAndVPL && view && view == this) +   { +       if (m_currentFocus == VPLFocus && !qConfig.quantaRefreshOnFocus) +          m_sourceUpdateTimer.start(qConfig.quantaRefreshDelay); +       if (m_currentFocus == SourceFocus && !qConfig.kafkaRefreshOnFocus) +          m_VPLUpdateTimer.start(qConfig.kafkaRefreshDelay); +   } +} + +void QuantaView::slotVPLGetFocus(bool focus) +{ +  // is Quanta exiting? +  if (!quantaApp) return; +#ifdef LIGHT_DEBUG +  kdDebug(25001)<< "slotVPLGetFocus(" << focus << ")" << endl; +#endif +  int contentsX, contentsY; +  KAction *action; + +  if(focus) +  { +    //We reload the kafka part from the Node Tree +    if (m_currentViewsLayout == SourceAndVPL && m_currentFocus == SourceFocus) +    { + +      contentsX = m_kafkaDocument->getKafkaWidget()->view()->contentsX(); +      contentsY = m_kafkaDocument->getKafkaWidget()->view()->contentsY(); + +      //Reload the kafka Editor only if Quanta was modified or if something has happened (e.g. a reparse) +      //and NEED a kafka reload. +      if  (parser->parsingNeeded()) +          baseNode = parser->rebuild(m_document); +      reloadVPLView(); +      //doesn't work! +      m_kafkaDocument->getKafkaWidget()->view()->setContentsPos(contentsX, contentsY); +    } + +    //We disable some actions which doesn't work on kafka for the moment +    action = quantaApp->actionCollection()->action("tag_edit_table"); +    if(action) +      action->setEnabled(false); +    action = 0L; +    action = quantaApp->actionCollection()->action("tag_quick_list"); +    if(action) +      action->setEnabled(false); +    action = 0L; +    action = quantaApp->actionCollection()->action("tag_color"); +    if(action) +      action->setEnabled(false); +    action = 0L; +    action = quantaApp->actionCollection()->action("tag_mail"); +    if(action) +      action->setEnabled(false); +    action = 0L; +    action = quantaApp->actionCollection()->action("tag_misc"); +    if(action) +      action->setEnabled(false); +    action = 0L; +    action = quantaApp->actionCollection()->action("tag_frame_wizard"); +    if(action) +      action->setEnabled(false); +    action = 0L; +    action = quantaApp->actionCollection()->action("insert_css"); +    if(action) +      action->setEnabled(false); +    action = 0L; +    action = quantaApp->actionCollection()->action("insert_char"); +    if(action) +      action->setEnabled(false); + +   //TEMPORARY: Enable VPL undo/redo logging +   m_document->docUndoRedo->turnOn(true); + +    m_currentFocus = VPLFocus; +    reloadUpdateTimers(); + } +} + +void QuantaView::slotSourceGetFocus() +{ +  // is Quanta exiting? +  if (!quantaApp) return; +#ifdef LIGHT_DEBUG +  kdDebug(25001)<< "slotSourceGetFocus(true)" << endl; +#endif +  KAction *action; + +  quantaApp->partManager()->setActivePart(m_document->doc(), m_document->view()); +  //We reload the quanta view from the Node Tree. +  if (m_currentViewsLayout == SourceAndVPL && m_currentFocus == VPLFocus) +  { +    reloadSourceView(); + +    //FIXME: the tree (and the output)is right, the pos aren't. +    //This will reparse the whole Node tree and reload kafka. +     baseNode = parser->parse(m_document); +  } + +  m_currentFocus = SourceFocus; +  reloadUpdateTimers(); + +    //We enable some actions which doesn't work on kafka for the moment +    action = quantaApp->actionCollection()->action("tag_edit_table"); +    if(action) +      action->setEnabled(true); +    action = 0L; +    action = quantaApp->actionCollection()->action("tag_quick_list"); +    if(action) +      action->setEnabled(true); +    action = 0L; +    action = quantaApp->actionCollection()->action("tag_color"); +    if(action) +      action->setEnabled(true); +    action = 0L; +    action = quantaApp->actionCollection()->action("tag_mail"); +    if(action) +      action->setEnabled(true); +    action = 0L; +    action = quantaApp->actionCollection()->action("tag_misc"); +    if(action) +      action->setEnabled(true); +    action = 0L; +    action = quantaApp->actionCollection()->action("tag_frame_wizard"); +    if(action) +      action->setEnabled(true); +    action = 0L; +    action = quantaApp->actionCollection()->action("insert_css"); +    if(action) +      action->setEnabled(true); +    action = 0L; +    action = quantaApp->actionCollection()->action("insert_char"); +    if(action) +      action->setEnabled(true); + +    //TEMPORARY: Disable VPL undo/redo logging +    m_document->docUndoRedo->turnOn(false); + +} + +/** Reloads both views ONLY when changes have been made to the Node tree ONLY. */ +void QuantaView::reloadBothViews(bool force) +{ +  reloadSourceView(force); +  reloadVPLView(force); +} + +/** reload the Kafka view from the Node Tree. Set force to true if you want to reload even if not necessary. */ +void QuantaView::reloadVPLView(bool force) +{ +  if (m_document && (m_kafkaReloadingEnabled || force)) +      m_document->docUndoRedo->reloadKafkaEditor(force); +} + +/** reload the Quanta view from the Node Tree. Set force to true if you want to reload even if not necessary. */ +void QuantaView::reloadSourceView(bool force) +{ +  if (m_quantaReloadingEnabled || force) +      m_document->docUndoRedo->reloadQuantaEditor(force); +} + + +void QuantaView::VPLUpdateTimerTimeout() +{ +  if(quantaApp && m_currentFocus == SourceFocus) +    reloadVPLView(); +} + +void QuantaView::sourceUpdateTimerTimeout() +{ +  if(quantaApp && m_currentFocus == VPLFocus) +    reloadSourceView(); +} + +void QuantaView::slotVPLLoadingError(Node *) +{ +   emit showProblemsView(); +} + + +void QuantaView::slotSetCursorPositionInSource(int col, int line) +{ +  m_curCol = col; +  m_curLine = line; +  if (m_currentViewsLayout == SourceAndVPL || m_currentViewsLayout == SourceOnly) +    m_document->viewCursorIf->setCursorPositionReal(line, col); +} + +void QuantaView::dragEnterEvent(QDragEnterEvent *e) +{ +  e->accept(KURLDrag::canDecode(e)); +} + +void QuantaView::dropEvent(QDropEvent *e) +{ +   emit dragInsert(e); +} + +void QuantaView::resizeEvent(QResizeEvent *e) +{ +  QWidget::resizeEvent(e); +  resize(m_documentArea->width(), m_documentArea->height()); +} + +void QuantaView::resize(int width, int height) +{ +  if (m_plugin && m_plugin->widget()) +  { +      m_plugin->widget()->resize(width, height); +      return; +  } else +  if (m_customWidget) +  { +      m_customWidget->resize(width, height); +      return; +  } else +  if (!m_document) +      return; +  if (m_currentViewsLayout == SourceOnly) +    m_document->view()->resize(width, height); +  else +  if (m_currentViewsLayout == VPLOnly) +    m_kafkaDocument->getKafkaWidget()->view()->resize(width,height); +  else +  if (m_currentViewsLayout == SourceAndVPL) +  { +    m_splitter->resize(width, height); +    m_splitterSizes = m_splitter->sizes(); +  } +} + +void QuantaView::insertTag(const char *tag) +{ +   if (!m_document ) +      return; +  QString tagStr = QuantaCommon::tagCase(tag); +  const DTDStruct *dtd = m_document->currentDTD(true); +  bool single = QuantaCommon::isSingleTag(dtd->name, tagStr); +  bool optional = QuantaCommon::isOptionalTag(dtd->name, tagStr); + +  QString startTag = tagStr; +  startTag.prepend("<"); +  if ( dtd->singleTagStyle == "xml" && +       ( single || (optional && !qConfig.closeOptionalTags)) +     ) +  { +    startTag.append(" /"); +  } +  startTag.append(">"); + +  if ( (qConfig.closeTags && !single && !optional) || +       (qConfig.closeOptionalTags && optional) ) +  { +     m_document->insertTag( startTag, QString("</")+tagStr+">"); +  } +  else +  { +     m_document->insertTag(startTag); +  } +} + +//FIXME: Move out from here?? +/** Insert a new tag by bringing up the TagDialog. */ +void QuantaView::insertNewTag(const QString &tag, const QString &attr, bool insertInLine) +{ +  if (m_document) +  { +    if (m_currentFocus == QuantaView::VPLFocus || +        (m_currentFocus == QuantaView::SourceFocus && qConfig.smartTagInsertion)) +      insertOutputInTheNodeTree("", "", quantaApp->showTagDialogAndReturnNode(tag, attr)); +    else +    { +      QString selection; +      if (m_document->selectionIf) +        selection = m_document->selectionIf->selection(); +      TagDialog *dlg = new TagDialog(QuantaCommon::tagFromDTD(m_document->getDTDIdentifier(), tag), selection, attr, baseURL()); +      if (dlg->exec()) +      { +        dlg->insertTag(m_document, insertInLine); +      } + +      delete dlg; +    } +  } +} + +void QuantaView::insertOutputInTheNodeTree(const QString &str1, const QString &str2, Node *node) +{ +  if (!m_document) +    return; +#ifdef LIGHT_DEBUG +  if (node) +    kdDebug(25001)<< "QuantaView::insertOutputInTheNodeTree() - node : " << node->tag->name << +      " - type : " << node->tag->type << endl; +  else +    kdDebug(25001)<< "QuantaView::insertOutputInTheNodeTree() - str1 : " << str1 << +                " - str2 : " << str2 << endl; +#endif +  KafkaWidget *kafkaPart = m_kafkaDocument->getKafkaWidget(); +  NodeModifsSet *modifs; +  DOM::Node domNode, domStartContainer, domEndContainer; +  QString tagName; +  QTag *nodeQTag, *qTag, *nodeParentQTag; +  Node *nodeCursor, *startContainer, *endContainer, *nodeParent, *dummy; +  QPtrList<QTag> qTagList; +  int startCol, startLine, endCol, endLine; +  bool specialTagInsertion = false; +  long nodeOffset, startOffset, endOffset, domNodeOffset; +  QValueList<int> loc; +  uint line, col; +  bool smartTagInsertion, hasSelection, nodeTreeModified; + +  if (!node && str1.isEmpty() || node && !str1.isEmpty()) +      return; + +        //Three cases : +        //- Tag insertion in VPL +        //- Normal tag insertion in kate +        //- Smart tag insertion in kate +  smartTagInsertion = (m_currentFocus == QuantaView::SourceFocus && qConfig.smartTagInsertion); + +  if (m_currentFocus == QuantaView::VPLFocus || smartTagInsertion) +  { +    modifs = new NodeModifsSet(); +    if (!node && !str1.isEmpty()) +    { +      //We build the node from the str1 +      node = kafkaCommon::createNode("", "", Tag::XmlTag, m_document); +      node->tag->parse(str1, m_document); +      node->tag->name = QuantaCommon::tagCase(node->tag->name); +      node->tag->single = QuantaCommon::isSingleTag(m_document->defaultDTD()->name, +              node->tag->name); +    } +    if (m_currentFocus == QuantaView::VPLFocus) +    { +      kafkaPart->getCurrentNode(domNode, domNodeOffset); +      nodeCursor = m_kafkaDocument->getNode(domNode); +    } +    else +    { +      m_document->viewCursorIf->cursorPositionReal(&line, &col); +      nodeCursor = parser->nodeAt(line, col, false); +    } + +    if (!nodeCursor) +        return; + +    nodeParent = nodeCursor; +    if (nodeParent->tag->type == Tag::Text) +        nodeParent = nodeParent->parent; + +  //Checking if at least one parent of node can have a Text Node as child, otherwise +  //it is impossible for the +  //user to add this node. In that case, try to insert the Node in the closest parent accepting it. +  //e.g. TR : a normal insertion would require to have the caret in the TABLE Node, but it is +              //impossible +    nodeQTag = QuantaCommon::tagFromDTD(m_document->defaultDTD(), +                                        node->tag->name); + +    if (!nodeQTag) +        return; + +    qTagList = nodeQTag->parents(); +#ifdef HEAVY_DEBUG +    kdDebug(25001)<< "nodeQTag name : " << nodeQTag->name() << endl; +    /**kdDebug(25001)<< nodeQTag->isChild("#text", false) << endl; +    kdDebug(25001)<< nodeQTag->isChild("#text", true) << endl;*/ +#endif +    for (qTag = qTagList.first(); qTag; qTag = qTagList.next()) +    { +      if (qTag->isChild("#text", false)) +          break; +      if (qTag == qTagList.getLast()) +          specialTagInsertion = true; +    } + +    if (m_currentFocus == QuantaView::VPLFocus) +    { +      m_kafkaDocument->translateKafkaIntoNodeCursorPosition(domNode, domNodeOffset, &dummy, nodeOffset); +      kafkaPart->selection(domStartContainer, startOffset, domEndContainer, endOffset); +      m_kafkaDocument->translateKafkaIntoNodeCursorPosition(domStartContainer, startOffset, +              &startContainer, startOffset); +      m_kafkaDocument->translateKafkaIntoNodeCursorPosition(domEndContainer, endOffset, +              &endContainer,endOffset); +      hasSelection = kafkaPart->hasSelection(); +    } +      else +      if (m_document->selectionIfExt) +      { +        m_kafkaDocument->translateQuantaIntoNodeCursorPosition(line, col, &dummy, nodeOffset); +        startCol = m_document->selectionIfExt->selStartCol(); +        startLine = m_document->selectionIfExt->selStartLine(); +        endCol = m_document->selectionIfExt->selEndCol(); +        endLine = m_document->selectionIfExt->selEndLine(); +        m_kafkaDocument->translateQuantaIntoNodeCursorPosition((unsigned)startLine, (unsigned)startCol, +                &startContainer, startOffset); +        m_kafkaDocument->translateQuantaIntoNodeCursorPosition((unsigned)endLine, (unsigned)endCol, +                &endContainer, endOffset); +        hasSelection = m_document->selectionIf->hasSelection(); +        if (startContainer == endContainer && startContainer->tag->type == Tag::Empty) +        { +          hasSelection = false; +        } +        if (endContainer && endContainer->tag->type == Tag::XmlTag && endOffset < (signed)endContainer->tag->tagStr().length()) +        { +          endContainer = endContainer->previousSibling(); +          endOffset = (endContainer)?endContainer->tag->tagStr().length():0; +        } +     /**else +        { +          if (startContainer && startContainer->tag->type == Tag::Empty) +            startContainer = startContainer->nextNE(); +          if (endContainer && endContainer->tag->type == Tag::Empty) +            endContainer = endContainer->prevNE(); +        }*/ +      } + +      nodeTreeModified = false; +      if (specialTagInsertion) +      { +        //let's try to insert this node in the closest parent accepting it. +        while (nodeParent) +        { +          nodeParentQTag = +                  QuantaCommon::tagFromDTD(m_document->defaultDTD(), +                  nodeParent->tag->name); +          if (nodeParentQTag && nodeParentQTag->isChild(node)) +          { +            nodeCursor = kafkaCommon::createMandatoryNodeSubtree(node, +                    m_document); +            nodeOffset = 0; +            kafkaCommon::insertNodeSubtree(node, nodeParent, 0L, 0L, modifs); +            nodeTreeModified = true; +            break; +          } +          nodeParent = nodeParent->parent; +        } +      } +      else if (hasSelection && !nodeQTag->isSingle()) +      { +        //If some text is selected in kafka, surround the selection with the new Node. +        if(!startContainer || !endContainer) +            return; +        nodeTreeModified = kafkaCommon::DTDinsertRemoveNode(node, startContainer, (int)startOffset, +                endContainer, (int)endOffset, m_document, &nodeCursor, +                nodeOffset, modifs); +      } +      else +      { +        //Nothing is selected, simply inserting the Node if it is not an inline. +/*            if(!kafkaCommon::isInline(node->tag->name) || nodeQTag->isSingle()) +          {*/ +        nodeTreeModified = kafkaCommon::DTDinsertRemoveNode(node, nodeCursor, (int)nodeOffset, nodeCursor, +                (int)nodeOffset, m_document, &nodeCursor, nodeOffset, modifs); +//             } +      } + +      m_document->docUndoRedo->addNewModifsSet(modifs, undoRedo::NodeTreeModif); +      if (m_currentFocus == QuantaView::VPLFocus) +      { +                //view->reloadVPLView(); +                //Now update the VPL cursor position +        m_kafkaDocument->translateNodeIntoKafkaCursorPosition(nodeCursor, nodeOffset, domNode, +                domNodeOffset); +        if (!domNode.isNull() && domNode.nodeType() != DOM::Node::TEXT_NODE && +            !domNode.firstChild().isNull() && domNode.firstChild().nodeType() == +            DOM::Node::TEXT_NODE) +            domNode = domNode.firstChild(); +        if (!domNode.isNull()) +            kafkaPart->setCurrentNode(domNode, domNodeOffset); +      } +      else +      { +        //view->reloadSourceView(); +        //Now update the source cursor position +        m_kafkaDocument->translateNodeIntoQuantaCursorPosition(nodeCursor, nodeOffset, line, col); +        m_document->viewCursorIf->setCursorPositionReal(line, col); +      } +      if (!nodeTreeModified) +          quantaApp->slotStatusMsg(i18n("Cannot insert the tag: invalid location.")); + +    } +    else +    { +      m_document->insertTag(str1, str2); +    } +} + + +/** Returns the baseURL of the document. */ +KURL QuantaView::baseURL() +{ +  KURL base; +  if (m_document && !m_document->isUntitled() ) +  { +    base = QuantaCommon::convertToPath(m_document->url()); +  } else +  { +    base = Project::ref()->projectBaseURL(); +  } +  return base; +} + +void QuantaView::refreshWindow() +{ +  if (!m_document) +  { +    if (m_plugin) +       quantaApp->partManager()->setActivePart(m_plugin->part(), m_plugin->widget()); +       resize(width(), height()); +  } else +  { +/* +    kdDebug(24000) << "m_documentArea->height(): " << m_documentArea->height() << endl; +    kdDebug(24000) << "ToolbarTabWidget::ref()->height(): " << ToolbarTabWidget::ref()->height() << " hidden: " << ToolbarTabWidget::ref()->isHidden() << " visible: " << ToolbarTabWidget::ref()->isVisible() << endl; +    kdDebug(24000) <<"sum: " << m_documentArea->height() + ToolbarTabWidget::ref()->height() << endl; +    kdDebug(24000) << "height(): " << height() << endl; +    */ +    if (m_documentArea->height() + ToolbarTabWidget::ref()->height() - 1 > height() && !ToolbarTabWidget::ref()->isHidden()) //don't use isVisible alone instead of isHidden! +        resize(m_documentArea->width(), m_documentArea->height() - ToolbarTabWidget::ref()->height()); +      else if (ToolbarTabWidget::ref()->isHidden()) +        resize(width(), height()); +  } +} + +void QuantaView::activated() +{ +  if (!m_document) +  { +    parser->setSAParserEnabled(false); +    quantaApp->slotReloadStructTreeView(); +    refreshWindow(); +    return; +  } +  ToolbarTabWidget::ref()->reparent(this, 0, QPoint(), qConfig.enableDTDToolbar); +  m_viewLayout->addWidget(ToolbarTabWidget::ref(), 0 , 0); +  quantaApp->partManager()->setActivePart(m_document->doc(), m_document->view()); +  m_document->checkDirtyStatus(); +  StructTreeView::ref()->useOpenLevelSetting = true; +  quantaApp->slotLoadToolbarForDTD(m_document->getDTDIdentifier()); + +  //TEMP : If the activated document is not a (X)HTML document, disable smartTagInsertion +  //Will be removed when VPL will support every DTD +  KAction *action = quantaApp->actionCollection()->action("smart_tag_insertion"); +  if(action && m_document->defaultDTD()->name.contains("HTML", false) == 0) +  { +    qConfig.smartTagInsertion = false; +    (static_cast<KToggleAction* >(action))->setChecked(false); +  } + +  reloadLayout(); +  refreshWindow(); + } + + +void QuantaView::deactivated() +{ +  if (m_plugin) +  { +    quantaApp->statusBar()->changeItem("", IDS_STATUS); +  } +  m_sourceUpdateTimer.stop(); +  m_VPLUpdateTimer.stop(); +} + +bool QuantaView::saveModified(bool ask) +{ +  if (!m_document) +    return true; + +  bool completed=true; +  QString fileName = m_document->url().fileName(); + +  if (m_document->isModified() ) +  { +    if (m_currentFocus == VPLFocus) +      reloadSourceView(); +    int want_save; +    if (ask) +      want_save = KMessageBox::warningYesNoCancel(this, +          i18n("The file \"%1\" has been modified.\nDo you want to save it?").arg(fileName), +          i18n("Warning"), KStdGuiItem::save(), KStdGuiItem::discard()); +    else +      want_save = KMessageBox::Yes; + +    switch (want_save) +    { +      case KMessageBox::Yes : +           if (m_document->isUntitled()) +           { +             completed = quantaApp->slotFileSaveAs(this); +           } +           else +           { +             completed = saveDocument(m_document->url()); +           }; + +           break; + +      case KMessageBox::No : +           { +      	     m_document->removeBackup(quantaApp->config()); +      	     completed=true; +	   } +           break; + +      case KMessageBox::Cancel : +           completed=false; +           break; + +      default: +           completed=false; +           break; +    } +  } else +    m_document->removeBackup(quantaApp->config()); +  return completed; +} + +bool QuantaView::saveDocument(const KURL& url) +{ +  if (url.isEmpty()) +    return false; + +  emit eventHappened("before_save", url.url(), QString::null); +  m_saveResult = true; +  KURL oldURL = m_document->url(); +  if (!m_document->isUntitled() && oldURL.isLocalFile()) +  { +    fileWatcher->removeFile(oldURL.path()); +//    kdDebug(24000) << "removeFile[saveDocument]: " << oldURL.path() << endl; +  } +  if (url.isLocalFile()) +  { +    if (!m_document->saveAs(url)) +    { +      fileWatcher->addFile(oldURL.path()); +//      kdDebug(24000) << "addFile[saveDocument]: " << oldURL.path() << endl; +      return false; //saving to a local file failed +    } else //successful saving to a local file +    { +      m_document->setDirtyStatus(false); +      m_document->removeBackup(quantaApp->config()); +      fileWatcher->addFile(m_document->url().path()); +//      kdDebug(24000) << "addFile[saveDocument, 2]: " << m_document->url().path() << endl; +    } +  } else //saving to a remote file +  { +    KTextEditor::Document *doc = m_document->doc(); +    m_eventLoopStarted = false; +    connect(doc, SIGNAL(canceled(const QString &)), this, SLOT(slotSavingFailed(const QString &))); +    connect(doc, SIGNAL(completed()), this, SLOT(slotSavingCompleted())); +    m_saveResult = m_document->saveAs(url); +    if (m_saveResult) +    { +      //start an event loop and wait until the saving finished +      QExtFileInfo internalFileInfo; +      m_eventLoopStarted = true; +      internalFileInfo.enter_loop(); +    } +    disconnect(doc, SIGNAL(canceled(const QString &)), this, SLOT(slotSavingFailed(const QString &))); +    disconnect(doc, SIGNAL(completed()), this, SLOT(slotSavingCompleted())); +    if (!m_saveResult) //there was an error while saving +    { +      if (oldURL.isLocalFile()) +      { +        fileWatcher->addFile(oldURL.path()); +//        kdDebug(24000) << "addFile[saveDocument, 3]: " << oldURL.path() << endl; +      } +      return false; +    } +  } +  // everything went fine +  if (oldURL != m_document->url()) +  { +      setCaption(m_document->url().fileName()); +  } +  emit eventHappened("after_save", m_document->url().url(), QString::null); +  return true; +} + +void QuantaView::slotSavingFailed(const QString &error) +{ +  Q_UNUSED(error); +  m_saveResult = false; +  if (m_eventLoopStarted) +    qApp->exit_loop(); +} + +void QuantaView::slotSavingCompleted() +{ +  m_saveResult = true; +  m_document->setDirtyStatus(false); +  m_document->removeBackup(quantaApp->config()); +  if (m_eventLoopStarted) +    qApp->exit_loop(); +} + +#include "quantaview.moc" | 
