summaryrefslogtreecommitdiffstats
path: root/quanta/src/quanta.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'quanta/src/quanta.cpp')
-rw-r--r--quanta/src/quanta.cpp5390
1 files changed, 5390 insertions, 0 deletions
diff --git a/quanta/src/quanta.cpp b/quanta/src/quanta.cpp
new file mode 100644
index 00000000..596dc7e3
--- /dev/null
+++ b/quanta/src/quanta.cpp
@@ -0,0 +1,5390 @@
+/***************************************************************************
+ quanta.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 by 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 <time.h>
+
+// include files for QT
+#include <qaction.h>
+#include <qdragobject.h>
+#include <qdir.h>
+#include <qprinter.h>
+#include <qpainter.h>
+#include <qwidgetstack.h>
+#include <qtabwidget.h>
+#include <qfile.h>
+#include <qlineedit.h>
+#include <qcheckbox.h>
+#include <qtabbar.h>
+#include <qradiobutton.h>
+#include <qimage.h>
+#include <qtimer.h>
+#include <qtextcodec.h>
+#include <qtextstream.h>
+#include <qtextedit.h>
+#include <qiodevice.h>
+#include <qcombobox.h>
+#include <qdockarea.h>
+#include <qdom.h>
+#include <qspinbox.h>
+#include <qeventloop.h>
+#include <qfontmetrics.h>
+#include <qclipboard.h>
+#include <qptrlist.h>
+#include <qbuffer.h>
+#include <qdatetime.h>
+
+
+// include files for KDE
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include <kaccelmanager.h>
+#include <kbugreport.h>
+#include <kcolordialog.h>
+#include <kcombobox.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kencodingfiledialog.h>
+#include <kfiledialog.h>
+#include <kmenubar.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <khtmlview.h>
+#include <kdialogbase.h>
+#include <kdeversion.h>
+#include <kkeydialog.h>
+#include <kinputdialog.h>
+#include <klibloader.h>
+#include <kdockwidget.h>
+#include <kstatusbar.h>
+#include <kpopupmenu.h>
+#include <kpushbutton.h>
+#include <kprocess.h>
+#include <kprogress.h>
+#include <ktempdir.h>
+#include <ktempfile.h>
+#include <ktextedit.h>
+#include <kdebug.h>
+#include <ktar.h>
+#include <kedittoolbar.h>
+#include <kaction.h>
+#include <kcharsets.h>
+#include <kdirwatch.h>
+#include <kstandarddirs.h>
+#include <ktabwidget.h>
+#include <ktip.h>
+#include <kmimetype.h>
+#include <kparts/partmanager.h>
+#include <kparts/part.h>
+#include <kstringhandler.h>
+#include <kstdguiitem.h>
+#include <kurldrag.h>
+
+#include <ktexteditor/editinterface.h>
+#include <ktexteditor/encodinginterface.h>
+#include <ktexteditor/selectioninterface.h>
+#include <ktexteditor/markinterface.h>
+#include <ktexteditor/viewcursorinterface.h>
+#include <ktexteditor/printinterface.h>
+#include <ktexteditor/popupmenuinterface.h>
+#include <ktexteditor/dynwordwrapinterface.h>
+#include <ktexteditor/encodinginterface.h>
+#include <ktexteditor/undointerface.h>
+#include <ktexteditor/document.h>
+#include <ktexteditor/view.h>
+#include <ktexteditor/clipboardinterface.h>
+
+#include <kio/netaccess.h>
+
+#ifdef ENABLE_CVSSERVICE
+#include "cvsservice.h"
+#endif
+
+
+// application specific includes
+#include "document.h"
+#include "quanta.h"
+#include "quantaview.h"
+#include "quantadoc.h"
+#include "qextfileinfo.h"
+#include "resource.h"
+
+#include "project.h"
+
+// For Kafka cut/copy/paste
+#include "wkafkapart.h"
+
+#include "whtmlpart.h"
+
+#include "abbreviation.h"
+#include "filemasks.h"
+#include "styleoptionss.h"
+#include "previewoptions.h"
+#include "parseroptions.h"
+#include "dtdselectdialog.h"
+#include "donationdialog.h"
+#include "fourbuttonmessagebox.h"
+#include "specialchardialog.h"
+#include "kafkasyncoptions.h"
+#include "htmldocumentproperties.h"
+#include "undoredo.h"
+
+#include "filestreeview.h"
+#include "structtreeview.h"
+#include "doctreeview.h"
+#include "templatestreeview.h"
+#include "tagattributetree.h"
+#include "projecttreeview.h"
+#include "scripttreeview.h"
+#include "servertreeview.h"
+#include "variableslistview.h"
+#include "debuggerbreakpointview.h"
+
+#include "listdlg.h"
+#include "tagdialog.h"
+#include "tagmaildlg.h"
+#include "tagmisc.h"
+#include "tagquicklistdlg.h"
+#include "tableeditor.h"
+
+#include "csseditor.h"
+#include "cssselector.h"
+
+#include "framewizard.h"
+
+#include "debuggermanager.h"
+
+#include "parser.h"
+#include "dtdparser.h"
+
+#include "annotationoutput.h"
+#include "messageoutput.h"
+
+#include "dtepeditdlg.h"
+#include "actionconfigdialog.h"
+#include "toolbarxmlgui.h"
+#include "tagaction.h"
+#include "toolbartabwidget.h"
+#include "dcopquanta.h"
+#include "tagmiscdlg.h"
+
+#include "quantaplugininterface.h"
+#include "quantaplugin.h"
+#include "dtds.h"
+#include "dcopsettings.h"
+#include "quanta_init.h"
+#include "viewmanager.h"
+#include "debuggerui.h"
+#include "newstuff.h"
+#include "quantanetaccess.h"
+
+extern int NN;
+
+const QString resourceDir = QString(QUANTA_PACKAGE) + "/";
+
+// from kfiledialog.cpp - avoid qt warning in STDERR (~/.xsessionerrors)
+static void silenceQToolBar(QtMsgType, const char *){}
+
+QuantaApp::QuantaApp(int mdiMode) : DCOPObject("WindowManagerIf"), KMdiMainFrm( 0, "Quanta", (KMdi::MdiMode) mdiMode)
+
+{
+ setStandardToolBarMenuEnabled(true);
+ createStandardStatusBarAction();
+ m_quantaInit = new QuantaInit(this);
+ dcopSettings = new DCOPSettings;
+ dcopQuanta = new DCOPQuanta;
+ DTDs::ref(this);
+ quantaStarted = true;
+ tempFileList.setAutoDelete(true);
+ m_toolbarList.setAutoDelete(true);
+ userToolbarsCount = 0;
+ baseNode = 0L;
+ currentToolbarDTD = QString::null;
+ m_config=kapp->config();
+ idleTimer = new QTimer(this);
+ connect(idleTimer, SIGNAL(timeout()), SLOT(slotIdleTimerExpired()));
+ m_idleTimerEnabled = true;
+
+ qConfig.globalDataDir = KGlobal::dirs()->findResourceDir("data",resourceDir + "toolbar/quantalogo.png");
+ if (qConfig.globalDataDir.isEmpty())
+ {
+ quantaStarted = false;
+ kdWarning() << "***************************************************************************" << endl;
+ kdWarning() << i18n("Quanta data files were not found.") << endl;
+ kdWarning() << i18n("You may have forgotten to run \"make install\", or your KDEDIR, KDEDIRS or PATH are not set correctly.") << endl;
+ kdWarning() << "***************************************************************************" << endl;
+ QTimer::singleShot(20, kapp, SLOT(quit()));
+ return;
+ }
+ qConfig.enableDTDToolbar = true;
+
+ // connect up signals from KXXsldbgPart
+ connectDCOPSignal(0, 0, "debuggerPositionChangedQString,int)", "newDebuggerPosition(QString,int)", false );
+ connectDCOPSignal(0, 0, "editorPositionChanged(QString,int,int)", "newCursorPosition(QString,int,int)", false );
+ connectDCOPSignal(0, 0, "openFile(QString,int,int)", "openFile(QString,int,int)", false);
+
+ m_partManager = new KParts::PartManager(this);
+ // When the manager says the active part changes,
+ // the builder updates (recreates) the GUI
+ connect(m_partManager, SIGNAL(activePartChanged(KParts::Part * )),
+ this, SLOT(slotActivePartChanged(KParts::Part * )));
+ connect(this, SIGNAL(dockWidgetHasUndocked(KDockWidget *)), this, SLOT(slotDockWidgetHasUndocked(KDockWidget *)));
+ connect(tabWidget(), SIGNAL(initiateDrag(QWidget *)), this, SLOT(slotTabDragged(QWidget*)));
+
+ m_oldKTextEditor = 0L;
+ m_previewToolView = 0L;
+ m_documentationToolView = 0L;
+ m_previewedDocument = 0L;
+ m_previewVisible = false;
+ m_newDTEPStuff = 0L;
+ m_newToolbarStuff = 0L;
+ m_newTemplateStuff = 0L;
+ m_newScriptStuff = 0L;
+ m_newDocStuff = 0L;
+ m_debugger = 0L;
+ m_parserEnabled = true;
+ cursorLine = 0;
+ cursorCol = 0;
+ emit eventHappened("quanta_start", QDateTime::currentDateTime().toString(Qt::ISODate), QString::null);
+ setAcceptDrops(true);
+ tabWidget()->installEventFilter(this);
+}
+
+
+QuantaApp::~QuantaApp()
+{
+ delete m_newDTEPStuff;
+ m_newDTEPStuff = 0L;
+ delete m_newToolbarStuff;
+ m_newToolbarStuff = 0L;
+ delete m_newTemplateStuff;
+ m_newTemplateStuff = 0L;
+ delete m_newScriptStuff;
+ m_newScriptStuff = 0L;
+ delete m_newDTEPStuff;
+ m_newDocStuff = 0L;
+ // disconnect(m_htmlPart, SIGNAL(destroyed(QObject *)));
+ // disconnect(m_htmlPartDoc, SIGNAL(destroyed(QObject *)));
+ disconnect(this, SIGNAL(lastChildViewClosed()), ViewManager::ref(), SLOT(slotLastViewClosed()));
+ //kdDebug(24000) << "QuantaApp::~QuantaApp" << endl;
+#ifdef ENABLE_CVSSERVICE
+ delete CVSService::ref();
+#endif
+ delete m_debugger;
+ m_debugger = 0L;
+ quantaApp = 0L;
+ delete m_doc;
+ m_doc = 0L;
+ kdDebug(24000) << "Node objects before delete :" << NN << " baseNode= " << baseNode << endl;
+ delete baseNode;
+ baseNode = 0;
+ delete parser;
+ parser = 0L;
+ delete idleTimer;
+ idleTimer = 0L;
+ delete m_actions;
+ m_actions = 0L;
+ cursorLine = 0;
+ cursorCol = 0;
+ tempFileList.clear();
+ for (uint i = 0; i < tempDirList.count(); i++)
+ {
+ KIO::NetAccess::del(KURL().fromPathOrURL(tempDirList.at(i)->name()), this);
+ }
+ tempDirList.clear();
+ QDictIterator<ToolbarEntry> iter(m_toolbarList);
+ ToolbarEntry *p_toolbar;
+ for( ; iter.current(); ++iter )
+ {
+ p_toolbar = iter.current();
+ delete p_toolbar->dom;
+ delete p_toolbar->menu;
+ delete p_toolbar->guiClient;
+ }
+
+ m_toolbarList.clear();
+ QStringList tmpDirs = KGlobal::dirs()->resourceDirs("tmp");
+ tmpDir = tmpDirs[0];
+ for (uint i = 0; i < tmpDirs.count(); i++)
+ {
+ if (tmpDirs[i].contains("kde-"))
+ tmpDir = tmpDirs[i];
+ }
+ QString infoCss = tmpDir;
+ infoCss += "quanta/info.css";
+ QFile::remove(infoCss);
+ QDir dir;
+ dir.rmdir(tmpDir + "quanta");
+
+ delete dcopSettings;
+ delete dcopQuanta;
+// delete m_partManager;
+
+ kdDebug(24000) << "Undeleted node objects :" << NN << endl;
+}
+
+void QuantaApp::setTitle(const QString& title)
+{
+ QString s = title;
+ if (Project::ref()->hasProject())
+ {
+ s = Project::ref()->projectName() + " : " + s;
+ }
+ setCaption(s);
+}
+
+void QuantaApp::slotFileNew()
+{
+ m_doc->openDocument(KURL());
+}
+
+void QuantaApp::slotFileOpen()
+{
+ QString myEncoding = defaultEncoding();
+ QString startDir;
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w && !w->isUntitled())
+ startDir = w->url().url();
+ else
+ startDir = Project::ref()->projectBaseURL().url();
+
+ KEncodingFileDialog::Result data;
+ data = KEncodingFileDialog::getOpenURLsAndEncoding(myEncoding, startDir,
+ "all/allfiles text/html text/xml application/x-php text/plain", this, i18n("Open File"));
+ slotFileOpen(data.URLs, data.encoding);
+}
+
+void QuantaApp::slotFileOpen(const KURL::List &urls, const QString& encoding)
+{
+ m_doc->blockSignals(true);
+ m_parserEnabled = false;
+ for (KURL::List::ConstIterator i = urls.begin(); i != urls.end(); ++i)
+ {
+ if (!QExtFileInfo::exists(*i, true, this))
+ {
+ KMessageBox::error(this, i18n("<qt>The file <b>%1</b> does not exist or is not a recognized mime type.</qt>").arg((*i).prettyURL(0, KURL::StripFileProtocol)));
+
+ } else
+ {
+ if (QuantaCommon::checkMimeGroup(*i, "text") ||
+ QuantaCommon::denyBinaryInsert(this) == KMessageBox::Yes)
+ slotFileOpen(*i, encoding);
+ }
+ }
+ m_doc->blockSignals(false);
+ m_parserEnabled = true;
+ reparse(true);
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ setTitle(w->url().prettyURL(0, KURL::StripFileProtocol));
+}
+
+void QuantaApp::slotFileOpen(const KURL &url)
+{
+ slotFileOpen(url, defaultEncoding());
+}
+
+void QuantaApp::slotFileOpen(const KURL &url, const QString& encoding)
+{
+ m_doc->openDocument(url, encoding);
+}
+
+void QuantaApp::slotFileOpen(const KURL &url, const QString& encoding, bool readOnly)
+{
+ m_doc->openDocument(url, encoding, true, readOnly);
+}
+
+void QuantaApp::slotFileOpenRecent(const KURL &url)
+{
+ if (!QExtFileInfo::exists(url, true, this))
+ {
+ if (KMessageBox::questionYesNo(this,
+ i18n("The file %1 does not exist.\n Do you want to remove it from the list?").arg(url.prettyURL(0, KURL::StripFileProtocol)), QString::null, KStdGuiItem::del(), i18n("Keep"))
+ == KMessageBox::Yes)
+ {
+ fileRecent->removeURL(url);
+ }
+ } else
+ if (QuantaCommon::checkMimeGroup(url, "text") ||
+ QuantaCommon::denyBinaryInsert(this) == KMessageBox::Yes)
+ {
+ slotFileOpen(url);
+ }
+ fileRecent->setCurrentItem(-1);
+ ViewManager::ref()->activeDocument()->view()->setFocus();
+}
+
+void QuantaApp::slotFileSave()
+{
+ QuantaView* view=ViewManager::ref()->activeView();
+ Document *w = view->document();
+ if (w)
+ {
+ w->checkDirtyStatus();
+ if (w->isUntitled())
+ slotFileSaveAs();
+ else
+ {
+ if(ViewManager::ref()->activeView() &&
+ ViewManager::ref()->activeView()->hadLastFocus() == QuantaView::VPLFocus)
+ w->docUndoRedo->reloadQuantaEditor();
+ view->saveDocument(w->url());
+ w->docUndoRedo->fileSaved();
+ }
+ }
+}
+
+bool QuantaApp::slotFileSaveAs(QuantaView *viewToSave)
+{
+ bool result = false;
+ QuantaView* view = viewToSave;
+ if (!view)
+ view = ViewManager::ref()->activeView();
+ Document *w = view->document();
+ if (w)
+ {
+ KURL oldURL = w->url();
+ w->checkDirtyStatus();
+ if (!w->isUntitled() && oldURL.isLocalFile())
+ {
+ fileWatcher->removeFile(oldURL.path());
+// kdDebug(24000) << "removeFile[slotFileSaveAs]: " << oldURL.path() << endl;
+ }
+
+ //FIXME: in katepart changing encoding saves the original file if it was modified, so it's useless in saveas...
+// QString myEncoding = dynamic_cast<KTextEditor::EncodingInterface*>(w->doc())->encoding();
+
+ bool gotPath = false;
+
+ KURL saveAsUrl;
+
+ if (fTab->isVisible())
+ {
+ saveAsUrl = fTab->currentURL();
+ if (fTab->currentKFileTreeViewItem() && fTab->currentKFileTreeViewItem()->isDir())
+ {
+ saveAsUrl.adjustPath(+1);
+ }
+ gotPath = true;
+ } else
+ if (ProjectTreeView::ref()->isVisible())
+ {
+ saveAsUrl = ProjectTreeView::ref()->currentURL();
+ if (ProjectTreeView::ref()->currentKFileTreeViewItem() && ProjectTreeView::ref()->currentKFileTreeViewItem()->isDir())
+ {
+ saveAsUrl.adjustPath(+1);
+ }
+ gotPath = true;
+ }
+ if (!gotPath || saveAsUrl.isEmpty())
+ {
+ if (w->isUntitled())
+ {
+ saveAsUrl = Project::ref()->projectBaseURL();
+ saveAsUrl.adjustPath(+1);
+ saveAsUrl.setFileName(oldURL.fileName());
+ } else
+ saveAsUrl = oldURL;
+ } else
+ if (w->isUntitled() && !saveAsUrl.path().endsWith("/"))
+ {
+ saveAsUrl.setPath(saveAsUrl.directory(false, false) + oldURL.fileName());
+ }
+
+//FIXME: in katepart changing encoding saves the original file if it was modified, so it's useless in saveas...
+ /*
+ KEncodingFileDialog::Result data;
+ data = KEncodingFileDialog::getSaveURLAndEncoding(myEncoding, saveAsUrl.url(),
+ "all/allfiles text/html text/xml application/x-php text/plain", this, i18n("Save File"));
+ KURL saveUrl = data.URLs[0];
+ bool found;
+ QString encoding = KGlobal::charsets()->codecForName(data.encoding, found)->name();
+ KTextEditor::EncodingInterface* encodingIf = dynamic_cast<KTextEditor::EncodingInterface*>(w->doc());
+ if (encodingIf && encodingIf->encoding() != encoding)
+ encodingIf->setEncoding(encoding);
+ */
+ KURL saveUrl = KFileDialog::getSaveURL(saveAsUrl.url(),
+ "all/allfiles text/html text/xml application/x-php text/plain", this, i18n("Save File"));
+
+ if (QuantaCommon::checkOverwrite(saveUrl, this) && view->saveDocument(saveUrl))
+ {
+ oldURL = saveUrl;
+ if (Project::ref()->hasProject() && !Project::ref()->contains(saveUrl) &&
+ KMessageBox::Yes == KMessageBox::questionYesNo(0,i18n("<qt>Do you want to add the<br><b>%1</b><br>file to project?</qt>").arg(saveUrl.prettyURL(0, KURL::StripFileProtocol)), QString::null, KStdGuiItem::add(), i18n("Do Not Add"))
+ )
+ {
+ if (saveUrl.isLocalFile())
+ {
+ QDir dir(saveUrl.path());
+ saveUrl.setPath(dir.canonicalPath());
+ }
+ Project::ref()->insertFile(saveUrl, true);
+ }
+ if (view->hadLastFocus() == QuantaView::VPLFocus)
+ w->docUndoRedo->reloadQuantaEditor();
+
+ w->docUndoRedo->fileSaved();
+ result = true;
+ }
+ if (oldURL.isLocalFile())
+ {
+ fileWatcher->addFile(oldURL.path());
+// kdDebug(24000) << "addFile[slotFileSaveAs]: " << oldURL.path() << endl;
+ }
+ }
+ return result;
+}
+
+void QuantaApp::saveAsTemplate(bool projectTemplate, bool selectionOnly)
+{
+ QuantaView *view = ViewManager::ref()->activeView();
+ Document *w = view->document();
+ if (!w) return;
+
+ KURL url;
+ int query;
+ KURL projectTemplateURL;
+ w->checkDirtyStatus();
+ QString localTemplateDir = locateLocal("data", resourceDir + "templates/");
+
+ do {
+ query = KMessageBox::Yes;
+
+ if (projectTemplate)
+ {
+ url = KFileDialog::getSaveURL(Project::ref()->templateURL().url(), QString::null, this);
+ } else
+ {
+ url = KFileDialog::getSaveURL(locateLocal("data", resourceDir + "templates/"), QString::null, this);
+ }
+
+ if (url.isEmpty()) return;
+
+ if (Project::ref()->hasProject())
+ projectTemplateURL = Project::ref()->templateURL();
+ if ( ((projectTemplate) && (projectTemplateURL.isParentOf(url)) ) ||
+ ((! projectTemplate) && (KURL(localTemplateDir).isParentOf(url))) )
+ {
+ if (!QuantaCommon::checkOverwrite(url, this))
+ query = KMessageBox::No;
+ } else
+ {
+ if (projectTemplate)
+ localTemplateDir = projectTemplateURL.path(1);
+ KMessageBox::sorry(this,i18n("You must save the templates in the following folder: \n\n%1").arg(localTemplateDir));
+ query = KMessageBox::No;
+ }
+ } while (query != KMessageBox::Yes);
+
+ if (query == KMessageBox::Cancel) return;
+
+ if (selectionOnly && w->selectionIf)
+ {
+ KTempFile *tempFile = new KTempFile(tmpDir);
+ tempFile->setAutoDelete(true);
+ QString content;
+ content = w->selectionIf->selection();
+ QTextStream stream(tempFile->file());
+ stream.setEncoding(QTextStream::UnicodeUTF8);
+ stream << content;
+ tempFile->file()->flush();
+ tempFile->close();
+ if (!QExtFileInfo::copy(KURL::fromPathOrURL(tempFile->name()), url, -1, true, false, this))
+ KMessageBox::error(this, i18n("<qt>There was an error while creating the template file.<br>Check that you have write access to <i>%1</i>.</qt>").arg(url.prettyURL(0, KURL::StripFileProtocol)), i18n("Template Creation Error"));
+ delete tempFile;
+ } else
+ {
+ view->saveDocument(url);
+ }
+
+ if (projectTemplate)
+ Project::ref()->insertFile(url, true);
+ if(ViewManager::ref()->activeView() &&
+ ViewManager::ref()->activeView()->hadLastFocus() == QuantaView::VPLFocus)
+ w->docUndoRedo->reloadQuantaEditor();
+
+ w->docUndoRedo->fileSaved();
+}
+
+void QuantaApp::slotFileSaveAsLocalTemplate()
+{
+ saveAsTemplate(false);
+}
+
+void QuantaApp::slotFileSaveAsProjectTemplate()
+{
+ saveAsTemplate(true);
+}
+
+
+void QuantaApp::slotFileSaveSelectionAsLocalTemplate()
+{
+ saveAsTemplate(false, true);
+}
+
+void QuantaApp::slotFileSaveSelectionAsProjectTemplate()
+{
+ saveAsTemplate(true, true);
+}
+
+void QuantaApp::slotFileSaveAll()
+{
+ ViewManager::ref()->saveAll();
+}
+
+void QuantaApp::slotFileReload(QuantaView *view)
+{
+ if (!view)
+ view = ViewManager::ref()->activeView();
+ Document *w = view->document();
+ if (!w || w->isUntitled() || !view->saveModified())
+ return;
+ w->setModified(false);
+ unsigned int line, col;
+ w->viewCursorIf->cursorPosition(&line, &col);
+ if (w->openURL(w->url()))
+ w->viewCursorIf->setCursorPosition(line, col);
+ reparse(true);
+}
+
+void QuantaApp::slotFileReloadAll()
+{
+//TODO: Implement it!
+}
+
+void QuantaApp::slotFileClose(const KURL &url)
+{
+ QuantaView *view = ViewManager::ref()->isOpened(url);
+ if (view)
+ {
+ ViewManager::ref()->removeView(view);
+ }
+}
+
+
+void QuantaApp::slotFileCloseAll()
+{
+ ViewManager::ref()->closeAll();
+ WHTMLPart *part = m_htmlPart;
+ part->closeURL();
+ part->begin(Project::ref()->projectBaseURL());
+ part->write(" ");
+ part->end();
+
+ slotNewStatus();
+}
+
+void QuantaApp::slotFileQuit()
+{
+ close();
+}
+
+
+void QuantaApp::slotEditFindInFiles()
+{
+ QuantaPlugin *fileReplacePlugin = m_pluginInterface->plugin("KFileReplace");
+ if (fileReplacePlugin)
+ fileReplacePlugin->run();
+}
+
+
+void QuantaApp::slotHelpTip()
+{
+ KTipDialog::showTip(this, QString::null, true);
+}
+
+void QuantaApp::slotStatusMsg(const QString &msg)
+{
+ statusbarTimer->stop();
+ statusBar()->changeItem(" " + KStringHandler::cPixelSqueeze(msg, statusBar()->fontMetrics(), progressBar->x() - 20), IDS_STATUS);
+ statusBar()->repaint();
+ kapp->processEvents(QEventLoop::ExcludeUserInput | QEventLoop::ExcludeSocketNotifiers);
+ statusbarTimer->start(10000, true);
+}
+
+/** repaint preview */
+void QuantaApp::slotRepaintPreview()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+ if (!m_previewVisible) return;
+ if (!m_previewToolView && qConfig.previewPosition != "Editor" ) return;
+
+ m_previewedDocument = 0L;
+ previewCopyMade = false;
+
+ KHTMLView *html = m_htmlPart->view();
+ int xOffset = html->contentsX(), yOffset = html->contentsY();
+
+ m_htmlPart->closeURL();
+ KParts::BrowserExtension *browserExtension = KParts::BrowserExtension::childObject(m_htmlPart);
+ KParts::URLArgs args(true, browserExtension->xOffset(), browserExtension->yOffset());
+ browserExtension->setURLArgs( args );
+ QString encoding = defaultEncoding();
+ KTextEditor::EncodingInterface* encodingIf = dynamic_cast<KTextEditor::EncodingInterface*>(w->doc());
+ if (encodingIf)
+ encoding = encodingIf->encoding();
+
+ KURL url;
+ m_htmlPart->setEncoding(encoding, true);
+ QStringList list;
+ if (m_noFramesPreview)
+ {
+ list = w->tagAreas("frameset", true, true);
+ if (list.isEmpty() || w->editIf->text().isEmpty())
+ m_noFramesPreview = false;
+ else
+ {
+ m_htmlPart->closeURL();
+ QStringList noframearea = w->tagAreas("noframes", false, true);
+ //find the frameset area
+ int bl, bc, el, ec;
+ QStringList l = QStringList::split('\n', list[0], true);
+ QStringList coordList = QStringList::split(',', l[0], true);
+ bl = coordList[0].toInt();
+ bc = coordList[1].toInt();
+ el = coordList[2].toInt();
+ ec = coordList[3].toInt();
+ QString noFramesText = w->text(0,0, bl, bc - 1);
+ noFramesText += noframearea[0];
+ noFramesText += w->text(el, ec + 1, w->editIf->numLines() - 1, w->editIf->lineLength(w->editIf->numLines() - 1));
+ noFramesText.replace(QRegExp("</?noframes[^>]*>", false), "");
+ //kdDebug(24000) << "NOFRAMES: " << noFramesText << endl;
+ if (w->isUntitled())
+ m_htmlPart->begin(Project::ref()->projectBaseURL(), xOffset, yOffset);
+ else
+ {
+ url = Project::ref()->urlWithPrefix(w->url());
+ m_htmlPart->setPreviewedURL(url);
+ m_htmlPart->begin(url, xOffset, yOffset);
+ }
+ m_htmlPart->write(noFramesText);
+ m_htmlPart->end();
+ }
+ }
+
+ if (!m_noFramesPreview)
+ {
+ m_htmlPart->closeURL();
+ QString text = w->editIf->text();
+ if (text.isEmpty())
+ {
+ text = i18n("<center><h3>The current document is empty...</h3></center>");
+ }
+ if (w->isUntitled())
+ {
+ m_htmlPart->begin(Project::ref()->projectBaseURL(), xOffset, yOffset);
+ m_htmlPart->write(text);
+ m_htmlPart->end();
+ } else
+ {
+ m_previewedDocument = w;
+ url = Project::ref()->urlWithPrefix(w->url());
+ m_htmlPart->setPreviewedURL(url);
+ KURL previewURL = w->url();
+ previewURL.setFileName("preview-" + previewURL.fileName());
+ //save the content to disk, so preview with prefix works
+ KTempFile *tmpFile = new KTempFile(tmpDir);
+ QString tempFileName = QFileInfo(*(tmpFile->file())).filePath();
+ tmpFile->setAutoDelete(true);
+ QString encoding = quantaApp->defaultEncoding();
+ KTextEditor::EncodingInterface* encodingIf = dynamic_cast<KTextEditor::EncodingInterface*>(w->doc());
+ if (encodingIf)
+ encoding = encodingIf->encoding();
+ if (encoding.isEmpty())
+ encoding = "utf8"; //final fallback
+ tmpFile->textStream()->setCodec(QTextCodec::codecForName(encoding));
+ *(tmpFile->textStream()) << w->editIf->text();
+ tmpFile->close();
+ if (!QExtFileInfo::copy(KURL::fromPathOrURL(tempFileName), previewURL, -1, true)) {
+ m_htmlPart->setPreviewedURL(KURL()); // copy failed, force the preview of the original
+ };
+ delete tmpFile;
+ m_htmlPart->openURL(url);
+ m_htmlPart->addToHistory(url.url());
+ }
+ }
+ m_htmlPart->show();
+}
+
+void QuantaApp::slotOpenFileInPreview(const KURL& a_url)
+{
+ WHTMLPart *part = m_htmlPart;
+ if (!part)
+ return;
+ slotShowPreviewWidget(true);
+ part->openURL(a_url);
+ part->show();
+}
+
+/** view image in preview */
+void QuantaApp::slotImageOpen(const KURL& url)
+{
+ slotShowPreviewWidget(true);
+ WHTMLPart *part = m_htmlPart;
+ QString text = "<html>\n<body>\n<div align=\"center\">\n<img src=\"";
+ text += url.fileName(); //TODO
+ text += "\">\n</div>\n</body>\n</html>\n";
+ part->closeURL();
+ KURL docURL = url;
+ docURL.setFileName("imagepreview.html");
+ part->begin(docURL);
+ part->write(text);
+ part->end();
+
+ part->show();
+}
+
+
+/** insert <img> tag for images or <a> for other */
+void QuantaApp::slotInsertTag(const KURL& url, DirInfo dirInfo)
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ KURL baseURL ;
+ if (w->isUntitled() )
+ {
+ baseURL = Project::ref()->projectBaseURL();
+ } else
+ {
+ baseURL = w->url();
+ baseURL.setFileName("");
+ }
+ KURL relURL = QExtFileInfo::toRelative(url, baseURL);
+ QString urlStr = relURL.url();
+ if (relURL.protocol() == baseURL.protocol())
+ urlStr = relURL.path();
+ bool isImage = false;
+
+ if (!dirInfo.preText.isEmpty() || !dirInfo.postText.isEmpty())
+ {
+ w->insertTag(dirInfo.preText+urlStr+dirInfo.postText);
+ } else
+ {
+ QString mimetype = KMimeType::findByURL(url)->name();
+ if (mimetype.contains("image"))
+ {
+ QString imgFileName;
+ KIO::NetAccess::download(url, imgFileName, this);
+ QImage img(imgFileName);
+ if (!img.isNull())
+ {
+ QString width,height;
+ width.setNum(img.width());
+ height.setNum(img.height());
+ QString imgTag = QuantaCommon::tagCase("<img ");
+ imgTag += QuantaCommon::attrCase("src=");
+ imgTag += QuantaCommon::quoteAttributeValue(urlStr);
+ imgTag += QuantaCommon::attrCase(" width=");
+ imgTag += QuantaCommon::quoteAttributeValue(width);
+ imgTag += QuantaCommon::attrCase(" height=");
+ imgTag += QuantaCommon::quoteAttributeValue(height);
+ if (w->currentDTD(true)->singleTagStyle == "xml")
+ imgTag += " />";
+ else
+ imgTag += ">";
+ w->insertTag(imgTag);
+ isImage = true;
+ }
+ KIO::NetAccess::removeTempFile(imgFileName);
+ }
+ if (!isImage)
+ {
+ QString tag = QuantaCommon::tagCase("<a ");
+ tag += QuantaCommon::attrCase("href=");
+ tag += QuantaCommon::quoteAttributeValue(urlStr);
+ tag += ">";
+ w->insertTag(tag, QuantaCommon::tagCase("</a>"));
+ }
+ }
+ w->view()->setFocus();
+ }
+}
+
+void QuantaApp::slotNewStatus()
+{
+ fileRecent->setEnabled(true);
+ actionCollection()->action("project_open_recent")->setEnabled(true);
+ QuantaView *view = ViewManager::ref()->activeView();
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ setTitle( w->url().prettyURL(0, KURL::StripFileProtocol) );
+
+ if (w->doc()->isReadWrite())
+ {
+ KToggleAction *a = dynamic_cast<KToggleAction*>(w->view()->actionCollection()->action("set_insert"));
+ if (a)
+ {
+ statusBar()->changeItem(a->isChecked() ? i18n(" OVR ") : i18n(" INS "),IDS_INS_OVR);
+ }
+ }
+ else
+ statusBar()->changeItem(i18n(" R/O "),IDS_INS_OVR);
+ statusBar()->changeItem(w->isModified() ? " * " : "",IDS_MODIFIED);
+
+ saveAction->setEnabled(w->isModified());
+ saveAllAction->setEnabled(ViewManager::ref()->isOneModified());
+
+ bool projectExists = Project::ref()->hasProject();
+
+ actionCollection()->action("toolbars_load_project")->setEnabled(projectExists);
+ actionCollection()->action("toolbars_save_project")->setEnabled(projectExists);
+ }
+ if (view)
+ {
+ view->updateTab();
+ }
+}
+
+void QuantaApp::slotOptionsConfigureKeys()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ KKeyDialog dlg( false, this );
+ QPtrList<KXMLGUIClient> toolbarGuiClients;
+ QDictIterator<ToolbarEntry> iter(m_toolbarList);
+ for( ; iter.current(); ++iter )
+ {
+ toolbarGuiClients.append(iter.current()->guiClient);
+ }
+ QPtrList<KXMLGUIClient> clients = guiFactory()->clients();
+ for( QPtrListIterator<KXMLGUIClient> it( clients );
+ it.current(); ++it )
+ {
+ if (toolbarGuiClients.contains(*it) <= 0) //no need to insert the collections of the toolbars as they are present in the main actionCollection
+ dlg.insert((*it)->actionCollection());
+ }
+ if (dlg.configure() == KKeyDialog::Accepted)
+ {
+ // this is needed for when we have multiple embedded kateparts and change one of them.
+ // it also needs to be done to their views, as they too have actioncollections to update
+ if (const QPtrList<KParts::Part> * partlist = m_partManager->parts())
+ {
+ QPtrListIterator<KParts::Part> it(*partlist);
+ while (KParts::Part* part = it.current())
+ {
+ if (KTextEditor::Document *doc = dynamic_cast<KTextEditor::Document*>(part))
+ {
+ KActionPtrList actionList = doc->actionCollection()->actions();
+ KActionPtrList::Iterator actionIt;
+ if (!w || w->doc() != doc)
+ {
+ for ( actionIt = actionList.begin(); actionIt != actionList.end(); ++actionIt)
+ {
+ (*actionIt)->setShortcut((*actionIt)->shortcutDefault());
+ }
+ }
+ doc->reloadXML();
+
+ QPtrList<KTextEditor::View> const & list = doc->views();
+ QPtrListIterator<KTextEditor::View> itt( list );
+ while (KTextEditor::View * view = itt.current())
+ {
+ if (!w || w->view() != view)
+ {
+ actionList = view->actionCollection()->actions();
+ for (actionIt = actionList.begin(); actionIt != actionList.end(); ++actionIt)
+ {
+ (*actionIt)->setShortcut((*actionIt)->shortcutDefault());
+ }
+ }
+ view->reloadXML();
+ ++itt;
+ }
+ }
+ ++it;
+ }
+ }
+
+ QDomDocument doc;
+ doc.setContent(KXMLGUIFactory::readConfigFile(xmlFile(), instance()));
+ QDomNodeList nodeList = doc.elementsByTagName("ActionProperties");
+ QDomNode node = nodeList.item(0).firstChild();
+ while (!node.isNull())
+ {
+ if (node.nodeName() == "Action")
+ {
+ TagAction *action = dynamic_cast<TagAction*>(actionCollection()->action(node.toElement().attribute("name")));
+ if (action)
+ {
+ action->setModified(true);
+ QDomElement el = action->data();
+ el.setAttribute("shortcut", action->shortcut().toString());
+ el = node.toElement();
+ node = node.nextSibling();
+ el.parentNode().removeChild(el);
+ } else
+ {
+ node = node.nextSibling();
+ }
+ }
+ }
+ }
+}
+
+void QuantaApp::slotConfigureToolbars(const QString& defaultToolbar)
+{
+ currentPageIndex = ToolbarTabWidget::ref()->currentPageIndex();
+ QDomNodeList nodeList;
+ ToolbarEntry *p_toolbar = 0L;
+
+ saveMainWindowSettings(KGlobal::config(), autoSaveGroup());
+ KEditToolbar *dlg;
+ if (defaultToolbar)
+ dlg = new KEditToolbar(defaultToolbar, factory(), this);
+ else
+ dlg = new KEditToolbar(factory(), this);
+
+ KMenuBar *mb = menuBar();
+ KActionCollection *ac = actionCollection();
+ //remove the manually added menus BEFORE the dlg shows up
+ if (m_debugger->UI())
+ {
+ m_debugger->UI()->hideMenu();
+ }
+ for (uint i = 0 ; i < mb->count(); i++)
+ {
+ if (mb->text(mb->idAt(i)) == i18n("&Window"))
+ {
+ mb->removeItem(mb->idAt(i));
+ break;
+ }
+ }
+ ToolbarTabWidget *tb = ToolbarTabWidget::ref();
+ QString toolbarId;
+ for (int i = 0; i < tb->count(); i++)
+ {
+ toolbarId = tb->id(i);
+ p_toolbar = quantaApp->m_toolbarList[toolbarId];
+ if (p_toolbar)
+ {
+ delete p_toolbar->menu;
+ p_toolbar->menu = 0L;
+ }
+ }
+
+ connect(dlg, SIGNAL(newToolbarConfig()), SLOT(slotNewToolbarConfig()));
+ dlg->exec();
+ delete dlg;
+ QPopupMenu *menu = 0L;
+ m_tagsMenu = static_cast<QPopupMenu*>(factory()->container("tags", this));
+ QString toolbarName;
+ for (int i = 0; i < tb->count(); i++)
+ {
+ toolbarName = tb->label(i);
+ toolbarId = tb->id(i);
+ p_toolbar = quantaApp->m_toolbarList[toolbarId];
+ if (p_toolbar)
+ {
+ menu = new QPopupMenu(m_tagsMenu);
+ nodeList = p_toolbar->guiClient->domDocument().elementsByTagName("Action");
+ for (uint i = 0; i < nodeList.count(); i++)
+ {
+ KAction *action = ac->action(nodeList.item(i).toElement().attribute("name"));
+ if (action)
+ action->plug(menu);
+ }
+
+ m_tagsMenu->insertItem(toolbarName,menu);
+ p_toolbar->menu = menu;
+ }
+ }
+
+ //add back the menus
+ m_pluginInterface->setPluginMenu(static_cast<QPopupMenu*>(factory()->container("plugins", this)));
+ m_pluginInterface->buildPluginMenu();
+ for (uint i = 0 ; i < mb->count(); i++)
+ {
+ if (mb->text(mb->idAt(i)) == i18n("&Settings"))
+ {
+ mb->insertItem(i18n("&Window"), windowMenu(), -1, i);
+ break;
+ }
+ }
+ if (m_debugger->UI())
+ {
+ m_debugger->UI()->showMenu();
+ }
+ tb->setCurrentPage(currentPageIndex);
+}
+
+void QuantaApp::slotOptionsConfigureToolbars()
+{
+ slotConfigureToolbars();
+}
+
+void QuantaApp::slotNewToolbarConfig()
+{
+ applyMainWindowSettings(KGlobal::config(), autoSaveGroup());
+ ToolbarTabWidget::ref()->setCurrentPage(currentPageIndex);
+}
+
+void QuantaApp::slotShowMenuBar()
+{
+ if (menuBar()->isVisible())
+ menuBar()->hide();
+ else
+ menuBar()->show();
+}
+
+void QuantaApp::slotOptionsConfigureActions()
+{
+ ActionConfigDialog dlg(m_toolbarList, this, "actions_config_dlg", true);
+ dlg.exec();
+}
+
+void QuantaApp::slotPreviewOptions()
+{
+ KMessageBox::information(this, i18n("Changes made in the preview configuration dialog are global and have effect on every application using the KHTML part to display web pages, including Konqueror."), i18n("Warning"), "configure_preview_warning");
+ KApplication::startServiceByDesktopName("quanta_preview_config");
+}
+
+void QuantaApp::slotOptions()
+{
+ KDialogBase *kd = new KDialogBase(KDialogBase::IconList,
+ i18n("Configure Quanta"),
+ KDialogBase::Ok | KDialogBase::Cancel,
+ KDialogBase::Ok, this, "tabdialog");
+
+ // Tag Style options
+ QVBox *page=kd->addVBoxPage(i18n("Tag Style"), QString::null, BarIcon("kwrite", KIcon::SizeMedium));
+ StyleOptionsS *styleOptionsS = new StyleOptionsS( (QWidget *)page);
+
+ styleOptionsS->tagCase->setCurrentItem( qConfig.tagCase);
+ styleOptionsS->attributeCase->setCurrentItem( qConfig.attrCase);
+ styleOptionsS->attributeQuotation->setCurrentItem( (qConfig.attrValueQuotation == '"') ? 0 : 1);
+ styleOptionsS->tagAutoClose->setChecked( qConfig.closeTags );
+ styleOptionsS->optionalTagAutoClose->setChecked( qConfig.closeOptionalTags );
+ styleOptionsS->useAutoCompletion->setChecked( qConfig.useAutoCompletion );
+ styleOptionsS->tagUpdateClosing->setChecked(qConfig.updateClosingTags);
+ styleOptionsS->replaceAccented->setChecked(qConfig.replaceAccented);
+
+ // Environment options
+ //TODO FileMasks name is not good anymore
+ page=kd->addVBoxPage(i18n("Environment"), QString::null, UserIcon("files", KIcon::SizeMedium ) );
+ FileMasks *fileMasks = new FileMasks((QWidget *)page);
+
+ fileMasks->lineMarkup->setText( qConfig.markupMimeTypes );
+ fileMasks->lineScript->setText( qConfig.scriptMimeTypes );
+ fileMasks->lineImage->setText( qConfig.imageMimeTypes );
+ fileMasks->lineText->setText( qConfig.textMimeTypes );
+ fileMasks->showDTDSelectDialog->setChecked(qConfig.showDTDSelectDialog);
+ m_config->setGroup("General Options");
+ fileMasks->showSplash->setChecked(m_config->readBoolEntry("Show Splash", true));
+ fileMasks->reloadProject->setChecked(m_config->readBoolEntry("Reload Project", true));
+ fileMasks->reloadFiles->setChecked(m_config->readBoolEntry("Reload Files", true));
+ if(!m_config->readEntry("Autosave interval").isEmpty())
+ fileMasks->sbAutoSave->setValue(m_config->readNumEntry("Autosave interval"));
+ //else default value 15
+
+ QStringList availableEncodingNames(KGlobal::charsets()->availableEncodingNames());
+ fileMasks->encodingCombo->insertStringList( availableEncodingNames );
+ QStringList::ConstIterator iter;
+ int iIndex = -1;
+ for (iter = availableEncodingNames.begin(); iter != availableEncodingNames.end(); ++iter)
+ {
+ ++iIndex;
+ if ((*iter).lower() == qConfig.defaultEncoding.lower())
+ {
+ fileMasks->encodingCombo->setCurrentItem(iIndex);
+ break;
+ }
+ }
+ QStringList lst = DTDs::ref()->nickNameList(true);
+ uint pos = 0;
+ for (uint i = 0; i < lst.count(); i++)
+ {
+ fileMasks->defaultDTDCombo->insertItem(lst[i]);
+ if (lst[i] == DTDs::ref()->getDTDNickNameFromName(qConfig.defaultDocType.lower()))
+ pos = i;
+ }
+ fileMasks->defaultDTDCombo->setCurrentItem(pos);
+
+ // Preview options
+ page=kd->addVBoxPage(i18n("User Interface"), QString::null, BarIcon("view_choose", KIcon::SizeMedium ) );
+ PreviewOptions *uiOptions = new PreviewOptions( (QWidget *)page );
+
+ uiOptions->setPosition(qConfig.previewPosition);
+ uiOptions->setDocPosition(qConfig.docPosition);
+ uiOptions->setWindowLayout(qConfig.windowLayout);
+ uiOptions->setCloseButtons(qConfig.showCloseButtons);
+ uiOptions->setToolviewTabs(qConfig.toolviewTabs);
+ uiOptions->setHiddenFiles(qConfig.showHiddenFiles);
+ uiOptions->setSaveTrees(qConfig.saveTrees);
+ if (m_config->hasGroup("Notification Messages"))
+ {
+ m_config->setGroup("Notification Messages");
+ uiOptions->warnBinaryOpening->setChecked(m_config->readEntry("Open Everything") != "yes");
+ uiOptions->warnEventActions->setChecked((m_config->readEntry("Warn about internal actions", "yes") != "yes") && (m_config->readEntry("Warn about external actions", "yes") != "yes"));
+ uiOptions->warnAll->setChecked(false);
+ } else
+ {
+ uiOptions->warnAll->setChecked(true);
+ uiOptions->warnBinaryOpening->setChecked(true);
+ uiOptions->warnEventActions->setChecked(true);
+ }
+ //kafka options
+ page = kd->addVBoxPage(i18n("VPL View"), QString::null, UserIcon("vpl_text", KIcon::SizeMedium));
+ KafkaSyncOptions *kafkaOptions = new KafkaSyncOptions( m_config, (QWidget *)page );
+
+ page=kd->addVBoxPage(i18n("Parser"), QString::null, BarIcon("kcmsystem", KIcon::SizeMedium ) );
+ ParserOptions *parserOptions = new ParserOptions( m_config, (QWidget *)page );
+
+ parserOptions->refreshFrequency->setValue(qConfig.refreshFrequency);
+ parserOptions->instantUpdate->setChecked(qConfig.instantUpdate);
+ parserOptions->showEmptyNodes->setChecked(qConfig.showEmptyNodes);
+ parserOptions->showClosingTags->setChecked(qConfig.showClosingTags);
+ parserOptions->spinExpand->setValue(qConfig.expandLevel);
+
+ page = kd->addVBoxPage(i18n("Abbreviations"), QString::null, BarIcon("fontsizeup", KIcon::SizeMedium));
+ AbbreviationDlg *abbreviationOptions = new AbbreviationDlg((QWidget*)(page));
+
+ bool reloadTrees = false;
+ kd->adjustSize();
+ if ( kd->exec() )
+ {
+ bool uiRebuildNeeded = false;
+ bool previewSettingsChanged = false;
+
+ qConfig.tagCase = styleOptionsS->tagCase->currentItem();
+ qConfig.attrCase = styleOptionsS->attributeCase->currentItem();
+ qConfig.attrValueQuotation = styleOptionsS->attributeQuotation->currentItem() == 0 ? '"': '\'';
+ qConfig.closeTags = styleOptionsS->tagAutoClose->isChecked();
+ qConfig.closeOptionalTags = styleOptionsS->optionalTagAutoClose->isChecked();
+ qConfig.useAutoCompletion = styleOptionsS->useAutoCompletion->isChecked();
+ qConfig.updateClosingTags = styleOptionsS->tagUpdateClosing->isChecked();
+ qConfig.replaceAccented = styleOptionsS->replaceAccented->isChecked();
+
+ qConfig.markupMimeTypes = fileMasks->lineMarkup->text();
+ qConfig.scriptMimeTypes = fileMasks->lineScript->text();
+ qConfig.imageMimeTypes = fileMasks->lineImage->text();
+ qConfig.textMimeTypes = fileMasks->lineText->text();
+ qConfig.showDTDSelectDialog = fileMasks->showDTDSelectDialog->isChecked();
+ qConfig.autosaveInterval = fileMasks->sbAutoSave->value();
+ autosaveTimer->start(60000 * qConfig.autosaveInterval, false);
+ m_config->setGroup("General Options");
+ m_config->writeEntry("Show Splash", fileMasks->showSplash->isChecked());
+ m_config->writeEntry("Reload Project", fileMasks->reloadProject->isChecked());
+ m_config->writeEntry("Reload Files", fileMasks->reloadFiles->isChecked());
+
+ qConfig.defaultEncoding = fileMasks->encodingCombo->currentText();
+ QString tmpStr = uiOptions->closeButtons();
+ if (tmpStr != qConfig.showCloseButtons)
+ uiRebuildNeeded = true;
+ qConfig.showCloseButtons = tmpStr;
+ uint tmp = uiOptions->toolviewTabs();
+ if (tmp != qConfig.toolviewTabs)
+ uiRebuildNeeded = true;
+ qConfig.toolviewTabs = tmp;
+ if (uiRebuildNeeded)
+ {
+ initTabWidget();
+ }
+ reloadTrees = (qConfig.showHiddenFiles != uiOptions->hiddenFiles());
+ qConfig.showHiddenFiles = uiOptions->hiddenFiles();
+ qConfig.saveTrees = uiOptions->saveTrees();
+ if (uiOptions->warnAll->isChecked())
+ m_config->deleteGroup("Notification Messages");
+ else
+ {
+ m_config->setGroup("Notification Messages");
+ m_config->writeEntry("Open Everything", uiOptions->warnBinaryOpening->isChecked() ? "" : "yes");
+ m_config->writeEntry("Warn about internal actions", uiOptions->warnEventActions->isChecked() ? "" : "yes");
+ m_config->writeEntry("Warn about external actions", uiOptions->warnEventActions->isChecked() ? "" : "yes");
+ }
+
+ qConfig.showEmptyNodes = parserOptions->showEmptyNodes->isChecked();
+ qConfig.showClosingTags = parserOptions->showClosingTags->isChecked();
+ qConfig.instantUpdate = parserOptions->instantUpdate->isChecked();
+ qConfig.refreshFrequency = parserOptions->refreshFrequency->value();
+ if (!qConfig.instantUpdate && qConfig.refreshFrequency > 0)
+ {
+ refreshTimer->changeInterval(qConfig.refreshFrequency*1000);
+ } else
+ {
+ refreshTimer->stop();
+ }
+ qConfig.expandLevel = parserOptions->spinExpand->value();
+ parserOptions->updateConfig();
+
+ kafkaOptions->updateConfig();
+ qConfig.quantaRefreshOnFocus = kafkaOptions->sourceFocusRefresh->isChecked();
+ qConfig.quantaRefreshDelay = kafkaOptions->sourceDelay->value();
+ qConfig.kafkaRefreshOnFocus = kafkaOptions->kafkaFocusRefresh->isChecked();
+ qConfig.kafkaRefreshDelay = kafkaOptions->kafkaDelay->value();
+ QuantaView *view = ViewManager::ref()->activeView();
+ if (view && view->document())
+ view->reloadUpdateTimers();
+ /**(static_cast<HTMLEnhancer *>(quantaApp->view()->getKafkaInterface()->mainEnhancer))->
+ showIconsForScripts(kafkaOptions->showScriptsIcon->isChecked());*/
+
+
+ qConfig.defaultDocType = DTDs::ref()->getDTDNameFromNickName(fileMasks->defaultDTDCombo->currentText());
+
+ abbreviationOptions->saveTemplates();
+
+ tmpStr = uiOptions->position();
+ if (tmpStr != qConfig.previewPosition)
+ {
+ if (m_previewVisible || m_previewToolView)
+ previewSettingsChanged = true;
+ slotShowPreviewWidget(false);
+ }
+ qConfig.previewPosition = tmpStr;
+ if (previewSettingsChanged)
+ slotShowPreviewWidget(true);
+ qConfig.docPosition = uiOptions->docPosition();
+ qConfig.windowLayout = uiOptions->layout();
+
+ m_htmlPart->closeURL();
+ m_htmlPart->begin( Project::ref()->projectBaseURL());
+ m_htmlPart->write(" ");
+ m_htmlPart->end();
+
+ reparse(true);
+ slotNewStatus();
+ }
+
+ m_config->sync();
+
+ saveOptions();
+
+ delete kd;
+ if (reloadTrees) emit reloadAllTrees();
+
+}
+
+void QuantaApp::slotShowPreviewWidget(bool show)
+{
+ QuantaView *view = ViewManager::ref()->activeView();
+ if (!view) return;
+ if (m_previewVisible == show) return;
+ if (show)
+ {
+ if (qConfig.previewPosition == "Editor")
+ {
+ delete m_previewToolView;
+ m_previewToolView = 0L;
+ view->addCustomWidget(m_htmlPart->view(), QString::null);
+ } else
+ {
+ if (!m_previewToolView)
+ {
+ m_previewToolView= addToolWindow(m_htmlPart->view(), prevDockPosition(m_htmlPart->view(), KDockWidget::DockBottom), getMainDockWidget());
+ connect(m_previewToolView->wrapperWidget(), SIGNAL(iMBeingClosed
+()), this, SLOT(slotPreviewBeingClosed()));
+ }
+ m_htmlPart->view()->show();
+ m_previewToolView->show();
+ }
+ m_previewVisible = true;
+ slotRepaintPreview();
+ } else
+ {
+ m_noFramesPreview = false;
+ m_previewVisible = false;
+ m_htmlPart->view()->reparent(this, 0, QPoint(), false);
+ m_htmlPart->view()->resize(0, 0);
+ m_htmlPart->view()->hide();
+ if (qConfig.previewPosition == "Editor")
+ {
+ view->addCustomWidget(0L, QString::null);
+ delete m_previewToolView;
+ m_previewToolView = 0L;
+ } else
+ {
+ delete m_previewToolView;
+ m_previewToolView = 0L;
+ }
+ if (m_previewedDocument)
+ {
+ KURL url = m_previewedDocument->url();
+ url.setFileName("preview-" + url.fileName());
+ KIO::NetAccess::del(url, this);
+ Document *w = view->document();
+ if (w)
+ w->view()->setFocus();
+ }
+ }
+
+ KToggleAction *ta = 0L;
+ int viewLayout = view->currentViewsLayout();
+ if (viewLayout == QuantaView::SourceOnly)
+ ta = (KToggleAction *) actionCollection()->action( "show_quanta_editor" );
+ else if (viewLayout == QuantaView::VPLOnly)
+ ta = (KToggleAction *) actionCollection()->action( "show_kafka_view" );
+ else if (viewLayout == QuantaView::SourceAndVPL)
+ {
+ ta = (KToggleAction *) actionCollection()->action( "show_kafka_and_quanta" );
+ }
+ if (ta)
+ {
+ ta->setChecked(!show);
+ }
+}
+
+void QuantaApp::slotChangePreviewStatus()
+{
+ if (qConfig.previewPosition == "Editor")
+ {
+ slotShowPreviewWidget(false);
+ } else
+ if (m_previewToolView && m_htmlPart->view()->isVisible())
+ {
+ //hiding the preview when it's in a toolview means that the current tab has changed,
+ //so we just repaint the content and restore the document on the disc.
+ m_previewVisible = true;
+ if (m_previewedDocument)
+ {
+ KURL url = m_previewedDocument->url();
+ url.setFileName("preview-" + url.fileName());
+ KIO::NetAccess::del(url, this);
+ }
+ slotRepaintPreview();
+ m_previewedDocument = 0L;
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ w->view()->setFocus();
+ }
+}
+
+void QuantaApp::slotPreviewHasFocus(bool focus)
+{
+ if (m_previewToolView)
+ {
+ if (focus)
+ slotRepaintPreview();
+ else
+ {
+ if (m_previewedDocument)
+ {
+ KURL url = m_previewedDocument->url();
+ url.setFileName("preview-" + url.fileName());
+ KIO::NetAccess::del(url, this);
+ }
+ m_previewedDocument = 0L;
+ }
+ }
+}
+
+void QuantaApp::slotToggleShowPreview()
+{
+ Document *w =ViewManager::ref()->activeDocument();
+ if (!w)
+ {
+ m_previewVisible = false;
+ return;
+ }
+ if (m_previewToolView)
+ {
+ m_previewVisible = m_htmlPart->view()->isVisible();
+ }
+ slotShowPreviewWidget(!m_previewVisible);
+ m_noFramesPreview = false;
+}
+
+void QuantaApp::slotShowNoFramesPreview()
+{
+ m_noFramesPreview = true;
+ slotToggleShowPreview();
+}
+
+
+void QuantaApp::newCursorPosition(const QString &file, int lineNumber, int columnNumber)
+{
+ Q_UNUSED(file);
+ typingInProgress = true;
+ startIdleTimer();
+ // updateTreeViews();
+ QString linenumber;
+ linenumber = i18n("Line: %1 Col: %2").arg(lineNumber).arg(columnNumber);
+ statusBar()->changeItem(linenumber, IDS_STATUS_CLM);
+ statusBar()->changeItem(i18n(" R/O "),IDS_INS_OVR);
+ statusBar()->changeItem("",IDS_MODIFIED);
+}
+
+void QuantaApp::newDebuggerPosition(const QString &file, int lineNumber)
+{
+ newCursorPosition(file, lineNumber, 0);
+}
+
+void QuantaApp::openFile(const QString &file, int lineNumber, int columnNumber)
+{
+ gotoFileAndLine(file, lineNumber, columnNumber);
+ slotNewStatus();
+}
+
+void QuantaApp::slotNewLineColumn()
+{
+ typingInProgress = true;
+ startIdleTimer();
+ // updateTreeViews();
+ QString linenumber;
+ oldCursorLine = cursorLine;
+ oldCursorCol = cursorCol;
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ w->viewCursorIf->cursorPosition(&cursorLine, &cursorCol);
+ linenumber = i18n("Line: %1 Col: %2").arg(cursorLine+1).arg(cursorCol+1);
+ statusBar()->changeItem(linenumber, IDS_STATUS_CLM);
+}
+
+void QuantaApp::updateTreeViews()
+{
+ QuantaView *view = ViewManager::ref()->activeView();
+ if (!view)
+ return;
+ Document *w = view->document();
+ if (w)
+ {
+ w->viewCursorIf->cursorPositionReal(&cursorLine, &cursorCol);
+ Node *node = parser->nodeAt(cursorLine, cursorCol);
+ if (node)
+ {
+ StructTreeView::ref()->showTagAtPos(node);
+ }
+ if(view->hadLastFocus() == QuantaView::SourceFocus)
+ aTab->setCurrentNode(node);
+ }
+}
+
+void QuantaApp::slotIdleTimerExpired()
+{
+ if (idleTimer)
+ {
+ typingInProgress = false;
+ updateTreeViews();
+ }
+}
+
+void QuantaApp::startIdleTimer()
+{
+ if (m_idleTimerEnabled && idleTimer)
+ idleTimer->start(500, true);
+}
+
+bool QuantaApp::slotEnableIdleTimer(bool enable)
+{
+ bool status = m_idleTimerEnabled;
+ if (enable)
+ startIdleTimer();
+ else
+ if (idleTimer)
+ idleTimer->stop();
+ m_idleTimerEnabled = enable;
+ return status;
+}
+
+void QuantaApp::slotReparse()
+{
+ reparse(false);
+}
+
+void QuantaApp::slotForceReparse()
+{
+ reparse(true);
+}
+
+/** reparse current document and initialize node. */
+void QuantaApp::reparse(bool force)
+{
+ if (!parser || !m_parserEnabled)
+ return;
+ //temp
+// if (!parser->activated()) return;
+ typingInProgress = false;
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ if (force)
+ {
+ baseNode = parser->parse(w, true);
+ }
+
+ if (w->hasChanged() || force)
+ {
+ slotReloadStructTreeView();
+ }
+
+ if (force)
+ {
+ uint line, col;
+ w->viewCursorIf->cursorPositionReal(&line, &col);
+ Node *node = parser->nodeAt(line, col);
+ if (StructTreeView::ref()->isVisible() && node)
+ StructTreeView::ref()->showTagAtPos(node);
+ aTab->setCurrentNode(node);
+ }
+ }
+
+ return;
+}
+
+void QuantaApp::setCursorPosition( int row, int col )
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ int numLines = w->editIf->numLines();
+
+ if ( row < numLines )
+ w->viewCursorIf->setCursorPositionReal(row, col);
+ else
+ w->viewCursorIf->setCursorPositionReal(numLines - 1, col);
+ }
+}
+
+void QuantaApp::gotoFileAndLine(const QString& filename, int line, int column)
+{
+ // First, check if we're already showing this file
+ Document *w = ViewManager::ref()->activeDocument();
+ KURL currentfilename, newfilename;
+ if(w)
+ {
+ currentfilename = w->url();
+ newfilename.setPath(filename);
+ }
+
+ // If a filename is specified and that file is not already active, openn it
+ if (!filename.isEmpty() && !currentfilename.equals(filename))
+ {
+ QuantaView* view = ViewManager::ref()->isOpened(KURL::fromPathOrURL(filename));
+ // If it's already opened, just activate it
+ if (view)
+ {
+ view->activate();
+ view->activated();
+ } else
+ {
+ // Otherwise open it
+ m_doc->openDocument( KURL::fromPathOrURL( filename ) );
+ }
+ }
+ // We have to do this again, in case activedocument changed since last check (ie a file was opened)
+ w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ int numLines = w->editIf->numLines();
+ if ( numLines > line && line >= 0 )
+ {
+ // Jump to the correct line/col
+ w->viewCursorIf->setCursorPositionReal(line, column);
+ }
+ w->view()->setFocus();
+ }
+}
+
+void QuantaApp::selectArea(int line1, int col1, int line2, int col2)
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ int numLines = w->editIf->numLines();
+
+ if ( line1 > numLines-1 )
+ line1 = numLines-1;
+
+ if ( line2 > numLines-1 )
+ line2 = numLines-1;
+
+ w->viewCursorIf->setCursorPositionReal(line2, col2);
+ if (w->selectionIf)
+ w->selectionIf->setSelection(line1, col1, line2, col2);
+ }
+}
+
+void QuantaApp::openDoc(const QString& url)
+{
+ if (qConfig.docPosition == "Tab")
+ {
+ QuantaView *docView = ViewManager::ref()->documentationView();
+ delete m_documentationToolView;
+ m_documentationToolView = 0L;
+ docView->activate();
+ } else
+ {
+ QuantaView *docView = ViewManager::ref()->documentationView(false);
+ if (docView)
+ ViewManager::ref()->removeView(docView);
+ if (!m_documentationToolView)
+ m_documentationToolView= addToolWindow(m_htmlPartDoc->view(), prevDockPosition(m_htmlPartDoc->view(), KDockWidget::DockBottom), getMainDockWidget());
+ m_htmlPartDoc->view()->show();
+ m_documentationToolView->show();
+ }
+ m_htmlPartDoc->view()->setFocus(); // activates the part
+
+ QString urlStr = url;
+ if (urlStr.startsWith("/"))
+ urlStr.prepend("file:");
+ KURL u(urlStr);
+ if (u == m_htmlPartDoc->url())
+ return;
+
+ m_htmlPartDoc->closeURL();
+ m_htmlPartDoc->openURL(u);
+ m_htmlPartDoc->show();
+ m_htmlPartDoc->addToHistory(urlStr);
+}
+
+void QuantaApp::slotContextHelp()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ QString currentWord = "";
+ parser->setSAParserEnabled(false);
+ reparse(true);
+ parser->setSAParserEnabled(true);
+ uint line, col;
+ w->viewCursorIf->cursorPositionReal(&line, &col);
+ Node *node = parser->nodeAt(line, col);
+ if (node && node->tag->type == Tag::XmlTag)
+ {
+ currentWord = node->tag->name;
+ } else
+ {
+ currentWord = w->currentWord();
+ }
+ const DTDStruct *dtd = w->currentDTD(true);
+ QString *url = dTab->contextHelp(dtd->documentation + "|" + currentWord);
+ if (url)
+ openDoc(*url);
+ }
+}
+
+void QuantaApp::slotShowMessagesView()
+{
+ makeDockVisible(dynamic_cast<KDockWidget*>(m_messageOutputView->wrapperWidget()));
+}
+
+void QuantaApp::slotShowProblemsView()
+{
+ makeDockVisible(dynamic_cast<KDockWidget*>(m_problemsOutputView->wrapperWidget()));
+}
+
+void QuantaApp::slotShowAnnotationView()
+{
+ makeDockVisible(dynamic_cast<KDockWidget*>(m_annotationOutputView->wrapperWidget()));
+}
+
+QWidget* QuantaApp::createContainer( QWidget *parent, int index, const QDomElement &element, int &id )
+{
+
+ QString tabname = element.attribute( "i18ntabname", "" );
+ QString idStr = element.attribute( "id", "" );
+
+ if ( element.tagName().lower() == "toolbar" && !tabname.isEmpty())
+ {
+//avoid QToolBar warning in the log
+ QtMsgHandler oldHandler = qInstallMsgHandler( silenceQToolBar );
+ ToolbarTabWidget *toolbarTab = ToolbarTabWidget::ref();
+ QWidget *w = new QWidget(toolbarTab, "ToolbarHoldingWidget" + element.attribute("name"));
+ QuantaToolBar *tb = new QuantaToolBar(w, element.attribute("name"), true, true);
+ tb->loadState(element);
+ tb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
+
+ //kdDebug(24000) << "tb->iconSize() " << tb->iconSize() << endl;
+ if (toolbarTab->iconText() == KToolBar::IconTextBottom)
+ {
+ tb->setGeometry(0,0, toolbarTab->width(), tb->iconSize() + QFontMetrics(KGlobalSettings::toolBarFont()).height() + 10);
+ toolbarTab->setFixedHeight(toolbarTab->tabHeight() + tb->height() + 3);
+ } else
+ {
+ tb->setGeometry(0,0, toolbarTab->width(), tb->iconSize() + 10);
+ toolbarTab->setFixedHeight(toolbarTab->tabHeight() + tb->height() + 3);
+ }
+/*
+ kdDebug(24000) << "tb->height() " << tb->height() << endl;
+ kdDebug(24000) << "toolbarTab->height() " << toolbarTab->height() << endl;
+ kdDebug(24000) << "toolbarTab->tabHeight() " << toolbarTab->tabHeight() << endl;
+*/
+ toolbarTab->insertTab(tb, tabname, idStr);
+ qInstallMsgHandler( oldHandler );
+
+ connect(tb, SIGNAL(removeAction(const QString&, const QString&)),
+ SLOT(slotRemoveAction(const QString&, const QString&)));
+ connect(tb, SIGNAL(editAction(const QString&)),
+ SLOT(slotEditAction(const QString&)));
+ return tb;
+ }
+
+ return KMainWindow::createContainer( parent, index, element, id );
+
+}
+
+void QuantaApp::removeContainer( QWidget *container, QWidget *parent, QDomElement &element, int id )
+{
+ if (dynamic_cast<QuantaToolBar*>(container))
+ {
+ ToolbarTabWidget::ref()->removePage(container);
+ }
+ else
+ KMainWindow::removeContainer( container, parent, element, id );
+}
+
+void QuantaApp::slotBack()
+{
+ if (ViewManager::ref()->documentationView(false) == ViewManager::ref()->activeView())
+ {
+ m_htmlPartDoc->back();
+ } else
+ if (m_previewVisible && (!m_previewToolView || m_htmlPart->view()->hasFocus()))
+ {
+ m_htmlPart->back();
+ } else
+ {
+ activatePrevWin();
+ }
+}
+
+void QuantaApp::slotForward()
+{
+ if (ViewManager::ref()->documentationView(false) == ViewManager::ref()->activeView())
+ {
+ m_htmlPartDoc->forward();
+ } else
+ if (m_previewVisible && (!m_previewToolView || m_htmlPart->view()->hasFocus()))
+ {
+ m_htmlPart->forward();
+ } else
+ {
+ activateNextWin();
+ }
+}
+
+void QuantaApp::slotInsertFile(const KURL& url)
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ w->insertFile(url);
+ }
+}
+
+void QuantaApp::slotContextMenuAboutToShow()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ QPopupMenu *popup = static_cast<QPopupMenu*>(factory()->container("popup_editor",this));
+ QString name;
+ uint line, col;
+ int bl, bc, el, ec;
+ QString tagStr;
+ w->viewCursorIf->cursorPositionReal(&line, &col);
+ Node *node = parser->nodeAt(line, col, false);
+ if (node)
+ {
+ if (node->tag->dtd()->family == Script)
+ {
+ StructTreeGroup group;
+ uint count = node->tag->dtd()->structTreeGroups.count();
+ for (uint i = 0; i < count; i++)
+ {
+ group = node->tag->dtd()->structTreeGroups[i];
+ if (group.hasFileName)
+ {
+ if (!group.hasDefinitionRx )
+ continue;
+ tagStr = node->tag->tagStr();
+ int pos = 0;
+ while (pos != -1)
+ {
+ pos = group.definitionRx.search(node->tag->cleanStr, pos);
+ if (pos != -1)
+ {
+ QString cleanName = node->tag->cleanStr.mid(pos, group.definitionRx.matchedLength());
+ name = tagStr.mid(pos, group.definitionRx.matchedLength());
+ node->tag->beginPos(bl, bc);
+ QString tmpStr = tagStr.left(pos);
+ int newLines = tmpStr.contains('\n');
+ bl += newLines;
+ int l = tmpStr.findRev('\n'); //the last EOL
+ bc = (l == -1) ? bc+pos : pos - l - 1;
+ newLines = name.contains('\n');
+ l = name.length();
+ el = bl + newLines;
+ ec = (newLines > 0) ? l - name.findRev('\n') : bc + l - 1;
+ pos += l;
+ int p = group.definitionRx.search(cleanName);
+ if (p != -1)
+ {
+ name = name.mid(p, group.definitionRx.matchedLength());
+ } else
+ name = "";
+ if (QuantaCommon::isBetween(line, col, bl, bc, el, ec) == 0)
+ {
+ break;
+ } else
+ {
+ name = "";
+ }
+ }
+ }
+ name.remove(group.fileNameRx);
+ if (!name.isEmpty())
+ break;
+ }
+ }
+ } else
+ {
+ QMap<QString, XMLStructGroup>::ConstIterator it = node->tag->dtd()->xmlStructTreeGroups.find(node->tag->name.lower());
+
+ if (it != node->tag->dtd()->xmlStructTreeGroups.constEnd())
+ {
+ XMLStructGroup group = it.data();
+ uint count = group.attributes.count();
+ for (uint j = 0; j < count; j++ )
+ if (node->tag->hasAttribute(group.attributes[j]))
+ {
+ name.append(node->tag->attributeValue(group.attributes[j]));
+ name.append(" | ");
+ }
+ name = name.left(name.length()-3);
+ name.remove('\n');
+ }
+ }
+ }
+ KAction *action = actionCollection()->action("open_file_under_cursor");
+ if (action)
+ {
+ if (!name.isEmpty())
+ {
+ KURL baseUrl = QExtFileInfo::path(w->url());
+ urlUnderCursor = baseUrl;
+ QuantaCommon::setUrl(urlUnderCursor, name.stripWhiteSpace());
+ urlUnderCursor = QExtFileInfo::toAbsolute(urlUnderCursor, baseUrl);
+ action->setText(i18n("Open File: %1").arg(KStringHandler::lsqueeze(urlUnderCursor.prettyURL(0, KURL::StripFileProtocol), 80)));
+ action->setEnabled(true);
+ } else
+ {
+ action->setText(i18n("Open File: none"));
+ action->setEnabled(false);
+ }
+ }
+ action = actionCollection()->action("upload_file");
+ if (action)
+ {
+ action->setEnabled(Project::ref()->contains(w->url()));
+ }
+
+ // If we have a debugger session active...
+ if(debugger() && debugger()->hasClient())
+ {
+ int startpos;
+ QString word;
+
+ // If we have a selection made, thats what we want to use for watching, setting etc
+ if (w->selectionIf && w->selectionIf->hasSelection())
+ {
+ word = w->selectionIf->selection();
+ }
+ else
+ {
+ // Otherwise, find the word under the cursor
+ word = w->editIf->textLine(w->viewCursorIf->cursorLine());
+ startpos = word.findRev(QRegExp("$|[^a-zA-Z0-9_]"), w->viewCursorIf->cursorColumn());
+
+ word.remove(0, startpos);
+ if(word.left(1) != "$")
+ word.remove(0, 1);
+
+ word = word.left(word.find(QRegExp("[^a-zA-Z0-9_]"), 1));
+ }
+ // If we have a linebreak, take everything before the break
+ startpos = word.find("\n");
+ if(startpos > 0)
+ word = word.left(startpos);
+
+ // Trim whitespace from the beginning and end of the string
+ word = word.stripWhiteSpace();
+
+ // now we have a word, possibly the name of a variable
+ popupWord = word;
+
+ // The word we display in the popup will be cut off not to make an obeast pop up menu
+ if(word.length() > 23)
+ {
+ word.mid(20);
+ word += "...";
+ }
+
+ // If we have the addwatch action...
+ action = actionCollection()->action("debug_addwatch");
+ if(action)
+ {
+ action->setText(i18n("Add Watch: '%1'").arg(word));
+ action->setEnabled(!word.isEmpty());
+
+ if(!action->isPlugged(popup))
+ action->plug(popup);
+ }
+
+ // Dito for the set action
+ action = actionCollection()->action("debug_variable_set");
+ if(action)
+ {
+ action->setText(i18n("Set Value of '%1'").arg(word));
+ action->setEnabled(!word.isEmpty());
+
+ if(!action->isPlugged(popup))
+ action->plug(popup);
+ }
+
+ // Dito for the "break when" action
+ action = actionCollection()->action("debug_conditional_break");
+ if(action)
+ {
+ action->setText(i18n("Break When '%1'...").arg(word));
+ action->setEnabled(!word.isEmpty());
+
+ if(!action->isPlugged(popup))
+ action->plug(popup);
+ }
+ }
+ else
+ {
+ action = actionCollection()->action("debug_addwatch");
+ if(action && action->isPlugged(popup))
+ action->unplug(popup);
+ action = actionCollection()->action("debug_variable_set");
+ if(action && action->isPlugged(popup))
+ action->unplug(popup);
+ action = actionCollection()->action("debug_conditional_break");
+ if(action && action->isPlugged(popup))
+ action->unplug(popup);
+ }
+ }
+
+}
+
+void QuantaApp::slotOpenFileUnderCursor()
+{
+ if (QExtFileInfo::exists(urlUnderCursor, true, this))
+ {
+ if (QuantaCommon::checkMimeGroup(urlUnderCursor, "text" ))
+ {
+ slotFileOpen(urlUnderCursor, defaultEncoding());
+ }
+ else if (QuantaCommon::checkMimeGroup(urlUnderCursor, "image" ))
+ {
+ slotShowPreviewWidget(true);
+ slotImageOpen(urlUnderCursor);
+ }
+ } else
+ {
+ KMessageBox::error(this, i18n("<qt>The file <b>%1</b> does not exist or is not a recognized mime type.</qt>").arg(urlUnderCursor.prettyURL(0, KURL::StripFileProtocol)));
+
+ }
+}
+
+/** Load an user toolbar file from the disk. */
+void QuantaApp::slotLoadToolbarFile(const KURL& url)
+{
+ QDictIterator<ToolbarEntry> it(m_toolbarList);
+ ToolbarEntry *p_toolbar;
+ while (it.current())
+ {
+ p_toolbar = it.current();
+ ++it;
+ if (url == p_toolbar->url)
+ return;
+ }
+ QDomDocument actionDom;
+
+ QTextStream str;
+ str.setEncoding(QTextStream::UnicodeUTF8);
+ QString fileName = url.path();
+
+ if ( url.fileName().endsWith(toolbarExtension) )
+ {
+ QDomDocument *toolbarDom = new QDomDocument();
+//extract the files from the archives
+ KTar tar(fileName);
+ if (tar.open(IO_ReadOnly))
+ {
+ QString base = QFileInfo(fileName).baseName();
+ KArchiveFile* file = (KArchiveFile *) tar.directory()->entry(base+".toolbar");
+ if (file)
+ {
+ QIODevice *device = file->device();
+ toolbarDom->setContent(device);
+ delete device;
+ }
+ file = (KArchiveFile *) tar.directory()->entry(base+".actions");
+ if (file)
+ {
+ QIODevice *device = file->device();
+ actionDom.setContent(device);
+ delete device;
+ }
+
+ tar.close();
+ }
+ if ( (toolbarDom->toString().isEmpty()) ) //|| (actionContent.isEmpty()))
+ {
+ KMessageBox::error(this, i18n("Cannot load the toolbars from the archive.\nCheck that the filenames inside the archives begin with the archive name."));
+ delete toolbarDom;
+ return;
+ }
+
+ QDomNodeList nodeList = toolbarDom->elementsByTagName("ToolBar");
+ QString name = nodeList.item(0).cloneNode().toElement().attribute("tabname");
+
+ //search for another toolbar with the same name
+ QPtrList<KXMLGUIClient> xml_clients = guiFactory()->clients();
+ QString newName = name;
+ QString i18nName = i18n(name.utf8());
+ QString origName = name;
+ bool found = false;
+ bool nameModified = false;
+ int count = 2;
+ do
+ {
+ uint index = 0;
+ while (index < xml_clients.count())
+ {
+ name = newName;
+ if (index == 0)
+ found = false;
+ nodeList = xml_clients.at(index)->domDocument().elementsByTagName("ToolBar");
+ for (uint i = 0; i < nodeList.count(); i++)
+ {
+ if ((nodeList.item(i).cloneNode().toElement().attribute("name").lower() ) == name.lower())
+ {
+ newName = origName + QString(" (%1)").arg(count);
+ i18nName = i18n(origName.utf8()) + QString(" (%1)").arg(count);
+ nameModified = true;
+ count++;
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ {
+ index = 0;
+ } else
+ {
+ index++;
+ }
+ }
+ } while (name == newName && found);
+ name = newName;
+
+ p_toolbar = new ToolbarEntry;
+
+ QDomDocument *dom = new QDomDocument();
+ dom->setContent(toolbarDom->toString());
+ p_toolbar->dom = dom;
+ p_toolbar->nameModified = nameModified;
+
+ QString s = i18nName.lower();
+ QString toolbarId = s;
+ QRegExp rx("\\s|\\.");
+ toolbarId.replace(rx, "_");
+ int n = 1;
+ while (m_toolbarList.find(toolbarId) != 0L)
+ {
+ toolbarId = s + QString("%1").arg(n);
+ toolbarId.replace(rx, "_");
+ n++;
+ }
+
+
+ userToolbarsCount++;
+
+ //Change the name also in the XML File -> create a temp XML file
+ KTempFile* tempFile = new KTempFile(tmpDir);
+ tempFile->setAutoDelete(true);
+
+ nodeList = toolbarDom->elementsByTagName("ToolBar");
+ QDomElement el = nodeList.item(0).toElement();
+ el.setAttribute("name", name.lower());
+ el.setAttribute("tabname", name);
+ el.setAttribute("i18ntabname", i18nName);
+ el.setAttribute("id", toolbarId);
+ nodeList = toolbarDom->elementsByTagName("text");
+ el.firstChild().setNodeValue(name);
+ tempFile->textStream()->setEncoding(QTextStream::UnicodeUTF8);
+ * (tempFile->textStream()) << toolbarDom->toString();
+ tempFile->close();
+
+ //create the new toolbar GUI from the temp file
+ ToolbarXMLGUI * toolbarGUI = new ToolbarXMLGUI(tempFile->name());
+
+ //setup the actions
+ nodeList = actionDom.elementsByTagName("action");
+ for (uint i = 0; i < nodeList.count(); i++)
+ {
+ QDomNode node = nodeList.item(i).cloneNode();
+ el = node.toElement();
+ QString actionName = el.attribute("name");
+ //if there is no such action yet, add to the available actions
+ if (!actionCollection()->action(actionName))
+ {
+ bool toggable = (el.attribute("toggable", "") == "true");
+ TagAction *tagAction = new TagAction(&el, this, toggable);
+ m_tagActions.append(tagAction);
+
+ //add the actions to every toolbar xmlguiclient
+ QDictIterator<ToolbarEntry> it(m_toolbarList);
+ while (it.current())
+ {
+ it.current()->guiClient->actionCollection()->insert(tagAction);
+ ++it;
+ }
+
+ //Compatility code (read the action shortcuts from quantaui.rc)
+ //TODO: Remove after upgrade from 3.1 is not supported
+ if (oldShortcuts.contains(actionName))
+ {
+ tagAction->setModified(true);
+ tagAction->data().setAttribute("shortcut", oldShortcuts[actionName]);
+ tagAction->setShortcut(KShortcut(oldShortcuts[actionName]));
+ }
+ } else
+ {
+ // kdDebug(24000) << "The action " << actionName << " is already present!" << endl;
+ TagAction *tagAction = dynamic_cast<TagAction*>(actionCollection()->action(actionName));
+ if (tagAction)
+ tagAction->setModified(true);
+ }
+ }
+
+ //add all actions to the xmlguiclient of this toolbar
+ for (uint i = 0 ; i < actionCollection()->count(); i++)
+ toolbarGUI->actionCollection()->insert(actionCollection()->action(i));
+
+ guiFactory()->addClient(toolbarGUI);
+
+ //Plug in the actions & build the menu
+ QPopupMenu *menu = new QPopupMenu;
+ KAction *action;
+ nodeList = toolbarGUI->domDocument().elementsByTagName("Action");
+ for (uint i = 0; i < nodeList.count(); i++)
+ {
+ action = actionCollection()->action(nodeList.item(i).cloneNode().toElement().attribute("name") );
+ if (action)
+ {
+ action->plug(menu);
+ }
+ }
+
+ m_tagsMenu->insertItem(i18nName, menu);
+ p_toolbar->menu = menu;
+
+ tempFileList.append(tempFile);
+ p_toolbar->guiClient = toolbarGUI;
+ p_toolbar->name = name;
+ p_toolbar->id = toolbarId;
+ p_toolbar->url = url;
+ p_toolbar->visible = true;
+ p_toolbar->user = true; //TODO
+ m_toolbarList.insert(toolbarId, p_toolbar);
+ delete toolbarDom;
+
+ slotToggleDTDToolbar(!allToolbarsHidden());
+ }
+}
+
+/** Show the toolbar which is in url. If it was not loaded yet, it loads the
+ toolbar from the file */
+void QuantaApp::showToolbarFile(const KURL &url)
+{
+ ToolbarEntry *p_toolbar = toolbarByURL(url);
+ if (!p_toolbar)
+ {
+ slotLoadToolbarFile(url);
+ p_toolbar = toolbarByURL(url);
+ if (p_toolbar)
+ {
+ p_toolbar->user = false;
+ userToolbarsCount--;
+ }
+ } else
+ {
+ QDomNodeList nodeList;
+ QPopupMenu *menu = new QPopupMenu;
+ KAction *action;
+ KActionCollection *ac = actionCollection();
+ nodeList = p_toolbar->guiClient->domDocument().elementsByTagName("Action");
+ for (uint i = 0; i < nodeList.count(); i++)
+ {
+ action = ac->action(nodeList.item(i).toElement().attribute("name") );
+ if (action)
+ {
+ action->plug(menu);
+ }
+ }
+ m_tagsMenu->insertItem(i18n(p_toolbar->name.utf8()),menu);
+ p_toolbar->menu = menu;
+ p_toolbar->guiClient->reloadXML();
+ guiFactory()->addClient(p_toolbar->guiClient);
+ p_toolbar->visible = true;
+ }
+}
+
+/** Load an user toolbar from the disk. */
+void QuantaApp::slotLoadToolbar()
+{
+ KURL::List urls = KFileDialog::getOpenURLs(locateLocal("data",resourceDir + "toolbars/"), "*"+toolbarExtension, this);
+ if (!urls.isEmpty())
+ {
+ for (KURL::List::ConstIterator it = urls.constBegin(); it != urls.constEnd(); ++it)
+ slotLoadToolbarFile(*it);
+ }
+}
+
+/** Load an user toolbar from the disk. */
+void QuantaApp::slotLoadGlobalToolbar()
+{
+ KURL::List urls = KFileDialog::getOpenURLs(qConfig.globalDataDir +resourceDir + "toolbars/", "*"+toolbarExtension+"\n*", this);
+ if (!urls.isEmpty())
+ {
+ for (KURL::List::ConstIterator it = urls.constBegin(); it != urls.constEnd(); ++it)
+ slotLoadToolbarFile(*it);
+ }
+}
+
+KURL QuantaApp::saveToolbarToFile(const QString& toolbarName, const KURL& destFile)
+{
+ KURL tarFile = destFile;
+
+ if (! destFile.fileName().endsWith(toolbarExtension))
+ {
+ tarFile.setFileName(destFile.fileName() + toolbarExtension);
+ }
+
+ QBuffer buffer;
+ buffer.open(IO_ReadWrite);
+ QString toolStr;
+ QTextStream toolStream(&toolStr, IO_ReadWrite);
+ toolStream.setEncoding(QTextStream::UnicodeUTF8);
+
+ QBuffer buffer2;
+ buffer2.open(IO_WriteOnly);
+ QTextStream actStr(&buffer2);
+ actStr.setEncoding(QTextStream::UnicodeUTF8);
+
+ QDomNodeList nodeList, nodeList2;
+
+ toolStream << "<!DOCTYPE kpartgui SYSTEM \"kpartgui.dtd\">\n<kpartgui name=\"quanta\" version=\"2\">\n";
+ actStr << QString("<!DOCTYPE actionsconfig>\n<actions>\n");
+
+//look up the clients
+ QPtrList<KXMLGUIClient> xml_clients = factory()->clients();
+ for (uint index = 0; index < xml_clients.count(); index++)
+ {
+ nodeList = xml_clients.at(index)->domDocument().elementsByTagName("ToolBar");
+ for (uint i = 0; i < nodeList.count(); i++)
+ {
+ //find the actual toolbar in the XML GUI
+ if ((nodeList.item(i).cloneNode().toElement().attribute("id") ) == toolbarName)
+ {
+
+ //find the actions registered to the toolbar
+ QDomNode n = nodeList.item(i).firstChild();
+ while (! n.isNull())
+ {
+ QDomElement e = n.toElement();
+ if (e.tagName() == "Action")
+ {
+ TagAction *action = dynamic_cast<TagAction*>(actionCollection()->action(e.attribute("name")));
+ if (action)
+ {
+ action->data().save(actStr,1);
+ action->setModified(false);
+ }
+ } else
+ if (e.tagName() == "_Separator_")
+ {
+ e.setTagName("Separator");
+ }
+ n = n.nextSibling();
+ }
+ QDomElement e = nodeList.item(0).toElement();
+ QString i18nName = e.attribute("i18ntabname");
+ QString id = e.attribute("id");
+ e.removeAttribute("i18ntabname");
+ e.removeAttribute("id");
+ nodeList.item(i).save(toolStream,2);
+ e.setAttribute("i18ntabname", i18nName);
+ e.setAttribute("id", id);
+ }
+ }
+ }
+ toolStream << QString("\n</kpartgui>");
+ actStr << QString("\n</actions>");
+ //buffer.flush();
+
+ ToolbarEntry *p_toolbar = m_toolbarList[toolbarName];
+ QDomDocument *oldDom = p_toolbar->dom;
+ QDomDocument *dom = new QDomDocument();
+ QString s = toolStr;
+ QString error;
+ int el, ec;
+ if (!dom->setContent(s, &error, &el, &ec))
+ kdError(24000) << QString("Error %1 at (%2, %3)").arg(error).arg(el).arg(ec)<<endl;
+ p_toolbar->dom = dom;
+
+ QTextStream bufferStr(&buffer);
+ bufferStr.setEncoding(QTextStream::UnicodeUTF8);
+ bufferStr << toolStr;
+ buffer.close();
+ buffer2.close();
+
+ KTempFile *tempFile = new KTempFile(tmpDir);
+ tempFile->setAutoDelete(true);
+ tempFile->close();
+ KTar tar(tempFile->name(), "application/x-gzip");
+ if (!tar.open(IO_WriteOnly))
+ return KURL();
+ if (!tar.writeFile(QFileInfo(tarFile.path()).baseName()+".toolbar", "user", "group", buffer.buffer().size(), buffer.buffer().data()))
+ return KURL();
+ if (!tar.writeFile(QFileInfo(tarFile.path()).baseName()+".actions", "user", "group", buffer2.buffer().size(), buffer2.buffer().data()))
+ return KURL();
+ tar.close();
+ if (!QExtFileInfo::copy(KURL::fromPathOrURL(tempFile->name()), tarFile, -1, true, false, this))
+ {
+ KMessageBox::error(this, i18n("<qt>An error happened while saving the <b>%1</b> toolbar.<br>"
+ "Check that you have write permissions for<br><b>%2</b>.<br><br>This might happen if you tried save to save a global toolbar as a simple user. Use <i>Save As</i> or <i>Toolbars->Save Toolbars->Save as Local Toolbar</i> in this case. </qt>").arg(p_toolbar->name).arg(tarFile.prettyURL(0, KURL::StripFileProtocol)), i18n("Toolbar Saving Error"));
+ tarFile = KURL();
+ delete p_toolbar->dom;
+ p_toolbar->dom = oldDom;
+ } else
+ delete oldDom;
+ delete tempFile;
+ return tarFile;
+}
+
+/** Saves a toolbar as local or project specific. */
+bool QuantaApp::saveToolbar(bool localToolbar, const QString& toolbarToSave, const KURL& destURL)
+{
+ int query;
+ KURL url;
+ KURL projectToolbarsURL;
+ QString toolbarName;
+ QString localToolbarsDir = locateLocal("data",resourceDir + "toolbars/");
+
+ if (toolbarToSave.isEmpty())
+ {
+ ToolbarTabWidget *tb = ToolbarTabWidget::ref();
+
+ QStringList lst;
+ QStringList idLst;
+ int current=0;
+ for (int i = 0; i < tb->count(); i++)
+ {
+ lst << tb->label(i);
+ idLst << tb->id(i);
+ if ( tb->tabLabel(tb->currentPage()) == tb->label(i) ) current=i;
+ }
+
+ bool ok = false;
+ QString res = KInputDialog::getItem(
+ i18n( "Save Toolbar" ),
+ i18n( "Please select a toolbar:" ), lst, current, false, &ok, this );
+ if ( !ok )
+ return false;
+
+ for (uint i = 0; i < lst.count(); i++)
+ {
+ if (lst[i] == res)
+ {
+ toolbarName = idLst[i];
+ break;
+ }
+ }
+ } else
+ {
+ toolbarName = toolbarToSave;
+ }
+ ToolbarEntry *p_toolbar = m_toolbarList[toolbarName];
+ QString toolbarFileName = p_toolbar->url.fileName(false);
+ QString toolbarRelPath = p_toolbar->url.url();
+ if (toolbarRelPath.startsWith("file://" + qConfig.globalDataDir))
+ {
+ toolbarRelPath.remove("file://" + qConfig.globalDataDir + resourceDir + "toolbars/");
+ toolbarRelPath.remove(toolbarFileName);
+ }
+ else
+ {
+ toolbarRelPath = "";
+ }
+ toolbarFileName.remove(".toolbar.tgz");
+ if (destURL.isEmpty())
+ {
+ do {
+ query = KMessageBox::Yes;
+
+ if (localToolbar)
+ {
+ url = KFileDialog::getSaveURL(localToolbarsDir + toolbarRelPath + toolbarFileName, "*"+toolbarExtension, this);
+ } else
+ {
+ url = KFileDialog::getSaveURL(Project::ref()->toolbarURL().url() + toolbarFileName, "*"+toolbarExtension, this);
+ }
+
+ if (url.isEmpty())
+ return false;
+
+ if (Project::ref()->hasProject())
+ projectToolbarsURL = Project::ref()->toolbarURL();
+ if ( ((!localToolbar) && (projectToolbarsURL.isParentOf(url)) ) ||
+ ((localToolbar) && (KURL(localToolbarsDir).isParentOf(url))) )
+ {
+ if (!QuantaCommon::checkOverwrite(url, this))
+ query = KMessageBox::No;
+ } else
+ {
+ if (!localToolbar)
+ localToolbarsDir = projectToolbarsURL.prettyURL();
+ KMessageBox::sorry(0,i18n("<qt>You must save the toolbars to the following folder: <br><br><b>%1</b></qt>")
+ .arg(localToolbarsDir));
+ query = KMessageBox::No;
+ }
+ } while (query != KMessageBox::Yes);
+ } else
+ {
+ url = destURL;
+ query = KMessageBox::Yes;
+ }
+ if( query != KMessageBox::Cancel )
+ {
+ KURL tarName = saveToolbarToFile(toolbarName, url);
+ if (tarName.isEmpty())
+ {
+ return false;
+ }
+ if (!localToolbar)
+ Project::ref()->insertFile(tarName, true);
+ }
+ return true;
+}
+
+/** Saves a toolbar as localspecific. */
+void QuantaApp::slotSaveLocalToolbar()
+{
+ saveToolbar(true);
+}
+/** Saves a toolbar as project specific. */
+void QuantaApp::slotSaveProjectToolbar()
+{
+ saveToolbar(false);
+}
+
+/** Adds a new, empty toolbar. */
+void QuantaApp::slotAddToolbar()
+{
+ bool ok;
+ QString name = KInputDialog::getText(i18n("New Toolbar"), i18n("Enter toolbar name:"), i18n("User_%1").arg(userToolbarsCount), &ok, this);
+ if (ok)
+ {
+ userToolbarsCount++;
+
+ QString toolbarId = name;
+ int n = 1;
+ while (m_toolbarList.find(toolbarId) != 0L)
+ {
+ toolbarId = name + QString("%1").arg(n);
+ n++;
+ }
+ toolbarId = toolbarId.lower();
+
+ KTempFile* tempFile = new KTempFile(tmpDir);
+ tempFile->setAutoDelete(true);
+ tempFile->textStream()->setEncoding(QTextStream::UnicodeUTF8);
+ * (tempFile->textStream()) << QString("<!DOCTYPE kpartgui SYSTEM \"kpartgui.dtd\">\n<kpartgui name=\"quanta\" version=\"2\">\n<ToolBar name=\"%1\" tabname=\"%2\" i18ntabname=\"%3\" id=\"%4\">\n<text>%5</text>\n</ToolBar>\n</kpartgui>\n")
+ .arg(name.lower()).arg(name).arg(name).arg(toolbarId).arg(name);
+ tempFile->close();
+
+ ToolbarXMLGUI * toolbarGUI = new ToolbarXMLGUI(tempFile->name());
+
+//add all actions to the xmlguiclient of this toolbar
+ for (uint i = 0 ; i < actionCollection()->count(); i++)
+ toolbarGUI->actionCollection()->insert(actionCollection()->action(i));
+
+ guiFactory()->addClient(toolbarGUI);
+ ToolbarTabWidget::ref()->setCurrentPage(ToolbarTabWidget::ref()->count()-1);
+ tempFileList.append(tempFile);
+ ToolbarEntry *p_toolbar = new ToolbarEntry;
+ p_toolbar->guiClient = toolbarGUI;
+
+ QDomDocument *dom = new QDomDocument(toolbarGUI->domDocument());
+
+ p_toolbar->dom = dom;
+ p_toolbar->name = name;
+ p_toolbar->user = true;
+ p_toolbar->visible = true;
+ p_toolbar->nameModified = false;
+ p_toolbar->menu = new QPopupMenu;
+ p_toolbar->id = toolbarId;
+ m_tagsMenu->insertItem(p_toolbar->name, p_toolbar->menu);
+ m_toolbarList.insert(toolbarId, p_toolbar);
+
+ slotToggleDTDToolbar(!allToolbarsHidden());
+ }
+}
+
+
+/** Removes a user toolbar from the toolbars. */
+bool QuantaApp::slotRemoveToolbar()
+{
+ ToolbarTabWidget *tb = ToolbarTabWidget::ref();
+ int i;
+
+ QStringList lst;
+ QStringList idLst;
+ int current=0, j =0;
+ for (i = 0; i < tb->count(); i++)
+ {
+ lst << tb->label(i);
+ idLst << tb->id(i);
+ if ( tb->tabLabel(tb->currentPage()) == tb->label(i) ) current=j;
+ j++;
+ }
+
+ bool ok = false;
+ QString res = KInputDialog::getItem(
+ i18n( "Remove Toolbar" ),
+ i18n( "Please select a toolbar:" ), lst, current, false, &ok, this );
+
+ if (ok)
+ {
+ QString id = res;
+ for (uint i = 0; i < lst.count(); i++)
+ {
+ if (lst[i] == res)
+ {
+ id = idLst[i];
+ break;
+ }
+ }
+ return slotRemoveToolbar(id);
+ } else
+ return false;
+
+}
+
+QString QuantaApp::createToolbarTarball()
+{
+ ToolbarTabWidget *tb = ToolbarTabWidget::ref();
+
+ QStringList lst;
+ QStringList idLst;
+ int current = 0;
+ for (int i = 0; i < tb->count(); i++)
+ {
+ lst << tb->label(i);
+ idLst << tb->id(i);
+ if ( tb->tabLabel(tb->currentPage()) == tb->label(i) ) current=i;
+ }
+
+ bool ok = false;
+ QString res = KInputDialog::getItem(
+ i18n( "Send Toolbar" ),
+ i18n( "Please select a toolbar:" ), lst, current, false, &ok, this );
+
+ if (!ok)
+ return QString::null;
+
+ QString toolbarName = res;
+ for (uint i = 0; i < lst.count(); i++)
+ {
+ if (lst[i] == toolbarName)
+ {
+ toolbarName = idLst[i];
+ break;
+ }
+ }
+ QString prefix="quanta";
+ KTempDir* tempDir = new KTempDir(tmpDir);
+ tempDir->setAutoDelete(true);
+ tempDirList.append(tempDir);
+ QString tempFileName=tempDir->name() + toolbarName;
+
+ KURL tempURL;
+ tempURL.setPath(tempFileName);
+ saveToolbarToFile(toolbarName, tempURL);
+
+ return tempFileName + ".toolbar.tgz";
+}
+
+/** Sends a toolbar in mail. */
+void QuantaApp::slotSendToolbar()
+{
+
+ QString tempFileName = createToolbarTarball();
+ if (tempFileName.isNull())
+ return;
+
+ QStringList toolbarFile;
+ toolbarFile += tempFileName;
+
+ TagMailDlg *mailDlg = new TagMailDlg( this, i18n("Send toolbar in email"));
+ QString toStr;
+ QString message = i18n("Hi,\n This is a Quanta Plus [http://quanta.kdewebdev.org] toolbar.\n\nHave fun.\n");
+ QString titleStr;
+ QString subjectStr;
+
+ mailDlg->TitleLabel->setText(i18n("Content:"));
+/* mailDlg->titleEdit->setFixedHeight(60);
+ mailDlg->titleEdit->setVScrollBarMode(QTextEdit::Auto);
+ mailDlg->titleEdit->setHScrollBarMode(QTextEdit::Auto);*/
+ if ( mailDlg->exec() ) {
+ if ( !mailDlg->lineEmail->text().isEmpty())
+ {
+ toStr = mailDlg->lineEmail->text();
+ subjectStr = (mailDlg->lineSubject->text().isEmpty())?i18n("Quanta Plus toolbar"):mailDlg->lineSubject->text();
+ if ( !mailDlg->titleEdit->text().isEmpty())
+ message = mailDlg->titleEdit->text();
+ } else
+ {
+ KMessageBox::error(this,i18n("No destination address was specified.\n Sending is aborted."),i18n("Error Sending Email"));
+ delete mailDlg;
+ return;
+ }
+
+ kapp->invokeMailer(toStr, QString::null, QString::null, subjectStr, message, QString::null, toolbarFile);
+ }
+ delete mailDlg;
+}
+
+void QuantaApp::slotDownloadToolbar()
+{
+ if (!m_newToolbarStuff)
+ m_newToolbarStuff = new QNewToolbarStuff("quanta/toolbar", this);
+ m_newToolbarStuff->downloadResource();
+}
+
+void QuantaApp::slotUploadToolbar()
+{
+ QString tempFileName = createToolbarTarball();
+ if (tempFileName.isNull())
+ return;
+ if (!m_newToolbarStuff)
+ m_newToolbarStuff = new QNewToolbarStuff("quanta/toolbar", this);
+// tempDirList.append(m_newToolbarStuff->uploadResource(tempFileName));
+ m_newToolbarStuff->uploadResource(tempFileName);
+}
+
+void QuantaApp::slotRenameToolbar()
+{
+ ToolbarTabWidget *tb = ToolbarTabWidget::ref();
+
+ QStringList lst;
+ QStringList idLst;
+ int current = 0;
+ for (int i = 0; i < tb->count(); i++)
+ {
+ lst << tb->label(i);
+ idLst << tb->id(i);
+ if ( tb->tabLabel(tb->currentPage()) == tb->label(i) ) current=i;
+ }
+
+ bool ok = false;
+ QString res = KInputDialog::getItem(
+ i18n( "Rename Toolbar" ),
+ i18n( "Please select a toolbar:" ), lst, current, false, &ok, this );
+ if (ok)
+ {
+ QString id = res;
+ for (uint i = 0; i < lst.count(); i++)
+ {
+ if (lst[i] == res)
+ {
+ id = idLst[i];
+ break;
+ }
+ }
+ slotRenameToolbar(id);
+ }
+}
+
+void QuantaApp::slotRenameToolbar(const QString& name)
+{
+ ToolbarEntry *p_toolbar = quantaApp->m_toolbarList[name];
+ if (p_toolbar)
+ {
+ bool ok;
+ QString newName = KInputDialog::getText(i18n("Rename Toolbar"), i18n("Enter the new name:"), p_toolbar->name, &ok, this);
+ if (ok && newName != p_toolbar->name)
+ {
+ m_toolbarList.take(name);
+ p_toolbar->name = newName;
+ QDomElement el = p_toolbar->guiClient->domDocument().firstChild().firstChild().toElement();
+ el.setAttribute("tabname", p_toolbar->name);
+ el.removeAttribute("i18ntabname");
+ el.setAttribute("name", p_toolbar->name.lower());
+ QDomNodeList nodeList = p_toolbar->guiClient->domDocument().elementsByTagName("text");
+ nodeList.item(0).firstChild().setNodeValue(p_toolbar->name);
+ //Rename the _Separator_ tags back to Separator, so they are not treated
+ //as changes
+ nodeList = p_toolbar->guiClient->domDocument().elementsByTagName("_Separator_");
+ for (uint i = 0; i < nodeList.count(); i++)
+ {
+ nodeList.item(i).toElement().setTagName("Separator");
+ }
+ KXMLGUIFactory::saveConfigFile(p_toolbar->guiClient->domDocument(),
+ p_toolbar->guiClient->xmlFile(), p_toolbar->guiClient->instance());
+ ToolbarTabWidget *tb = ToolbarTabWidget::ref();
+ for (int i = 0; i < tb->count(); i++)
+ {
+ if (tb->id(i) == name)
+ {
+ tb->setTabLabel(tb->page(i)->parentWidget(), i18n(p_toolbar->name.utf8()));
+ m_tagsMenu->changeItem(m_tagsMenu->idAt(i + 2), i18n(p_toolbar->name.utf8()));
+ break;
+ }
+ }
+ m_toolbarList.insert(name, p_toolbar);
+ }
+ }
+}
+
+/** Ask for save all the modified user toolbars. */
+bool QuantaApp::removeToolbars()
+{
+ QStringList names;
+ QDictIterator<ToolbarEntry> it(m_toolbarList);
+ for (;it.current();++it)
+ {
+ names += it.currentKey();
+ }
+ for (QStringList::ConstIterator iter = names.constBegin(); iter != names.constEnd(); ++iter)
+ {
+ if (!slotRemoveToolbar(*iter))
+ return false;
+ }
+
+ QString s = "<!DOCTYPE actionsconfig>\n<actions>\n</actions>\n";
+ m_actions->setContent(s);
+ TagAction *action;
+ for (uint i = 0; i < actionCollection()->count(); i++)
+ {
+ action = dynamic_cast<TagAction *>(actionCollection()->action(i));
+ if (action)
+ {
+ QDomElement el = action->data();
+ m_actions->firstChild().appendChild(el);
+ }
+ }
+
+ QFile f(KGlobal::instance()->dirs()->saveLocation("data")+resourceDir + "actions.rc" );
+ if (f.open( IO_ReadWrite | IO_Truncate ))
+ {
+ if (!m_actions->firstChild().firstChild().isNull())
+ {
+ QTextStream qts(&f);
+ qts.setEncoding(QTextStream::UnicodeUTF8);
+ m_actions->save(qts,0);
+ f.close();
+ } else
+ f.remove();
+ }
+
+ return true;
+}
+
+void QuantaApp::slotDeleteAction(KAction *action)
+{
+//remove all references to this action
+ QDomElement el = static_cast<TagAction*>(action)->data();
+ QString text = el.attribute("text");
+ QString actionName = action->name();
+
+ QPtrList<KXMLGUIClient> guiClients = factory()->clients();
+ KXMLGUIClient *guiClient = 0;
+ QDomNodeList nodeList;
+ for (uint i = 0; i < guiClients.count(); i++)
+ {
+ guiClient = guiClients.at(i);
+ guiClient->domDocument().setContent(KXMLGUIFactory::readConfigFile( guiClient->xmlFile(), guiClient->instance() ));
+ nodeList = guiClient->domDocument().elementsByTagName("Action");
+ for (uint j = 0; j < nodeList.count(); j++)
+ {
+ //we found a toolbar that contains the action
+ if (nodeList.item(j).toElement().attribute("name") == actionName)
+ {
+ nodeList.item(j).parentNode().removeChild(nodeList.item(j));
+ KXMLGUIFactory::saveConfigFile(guiClient->domDocument(), guiClient->xmlFile());
+ break;
+ }
+ }
+ guiClient->actionCollection()->take(action);
+ }
+ action->unplugAll();
+ delete action;
+ action = 0L;
+}
+
+void QuantaApp::slotRemoveAction(const QString& toolbarName, const QString& a_actionName)
+{
+ KAction *action = 0L;
+ QString actionName = a_actionName;
+ actionName.replace('&',"&&");
+ KActionCollection *ac = actionCollection();
+ uint actionCount = ac->count();
+ QString str;
+ for (uint i = 0; i < actionCount; i++)
+ {
+ str = ac->action(i)->text();
+ if (str == actionName || str.remove('&') == actionName)
+ {
+ action = ac->action(i);
+ break;
+ }
+ }
+ if (!action) //workaround for actionnames ending with "...". It's stripped from the end
+ //of the text when plugged into a toolbar.
+ {
+ actionName += "...";
+ for (uint i = 0; i < actionCount; i++)
+ {
+ if (ac->action(i)->text() == actionName)
+ {
+ action = ac->action(i);
+ break;
+ }
+ }
+ }
+
+ if (action)
+ {
+ ToolbarEntry *p_toolbar = quantaApp->m_toolbarList[toolbarName];
+ if (p_toolbar)
+ {
+ QDomNode node = p_toolbar->guiClient->domDocument().firstChild().firstChild().firstChild();
+ while (!node.isNull())
+ {
+ if (node.nodeName() == "Action" &&
+ node.toElement().attribute("name") == action->name())
+ {
+ action->unplug(ToolbarTabWidget::ref()->page(toolbarName));
+ action->unplug(p_toolbar->menu);
+ node.parentNode().removeChild(node);
+ }
+ node = node.nextSibling();
+ }
+ KXMLGUIFactory::saveConfigFile(p_toolbar->guiClient->domDocument(),
+ p_toolbar->guiClient->xmlFile(), p_toolbar->guiClient->instance());
+ }
+ }
+}
+
+void QuantaApp::slotEditAction(const QString& actionName)
+{
+ ActionConfigDialog dlg(m_toolbarList, this, "actions_config_dlg", true, 0, actionName);
+ dlg.exec();
+}
+
+void QuantaApp::slotNewAction()
+{
+ ActionConfigDialog dlg(m_toolbarList, this, "actions_config_dlg");
+ dlg.slotNewAction();
+ dlg.exec();
+}
+
+void QuantaApp::slotAssignActionToScript(const KURL& a_scriptURL, const QString& a_interpreter)
+{
+ ActionConfigDialog dlg(m_toolbarList, this, "actions_config_dlg");
+ QString name = a_scriptURL.fileName();
+ name.truncate(name.length() - QFileInfo(name).extension().length() - 1);
+ dlg.createScriptAction(name, a_interpreter + " " + a_scriptURL.path());
+ dlg.exec();
+}
+
+void QuantaApp::setDtep(const QString& dtepName, bool convert)
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ QString dtep = DTDs::ref()->getDTDNameFromNickName(dtepName);
+ if (!DTDs::ref()->find(dtep))
+ return;
+ w->setDTDIdentifier(dtep);
+ const DTDStruct *dtd = DTDs::ref()->find(w->getDTDIdentifier());
+ if (convert && dtd->family == Xml)
+ {
+ Tag *tag = 0L;
+ w->findDTDName(&tag);
+ if (tag)
+ {
+ int bLine, bCol, eLine, eCol;
+ tag->beginPos(bLine,bCol);
+ tag->endPos(eLine,eCol);
+ w->editIf->removeText(bLine, bCol, eLine, eCol+1);
+ w->viewCursorIf->setCursorPositionReal((uint)bLine, (uint)bCol);
+ w->insertText("<!DOCTYPE" + dtd->doctypeStr +">");
+ delete tag;
+ } else
+ {
+ w->viewCursorIf->setCursorPositionReal(0,0);
+ w->insertText("<!DOCTYPE" + dtd->doctypeStr + ">\n");
+ }
+ }
+ slotLoadToolbarForDTD(w->getDTDIdentifier());
+ QuantaView *view = ViewManager::ref()->activeView();
+ if (view)
+ view->activated();
+ reparse(true);
+ }
+}
+
+void QuantaApp::slotChangeDTD()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ KDialogBase dlg(this, 0L, true, i18n("DTD Selector"), KDialogBase::Ok | KDialogBase::Cancel);
+ DTDSelectDialog *dtdWidget = new DTDSelectDialog(&dlg);
+ dtdWidget->setMinimumHeight(130);
+ dlg.setMainWidget(dtdWidget);
+ int pos = -1;
+ int defaultIndex = 0;
+
+ QString oldDtdName = w->getDTDIdentifier();
+ QString defaultDocType = Project::ref()->defaultDTD();
+ QStringList lst = DTDs::ref()->nickNameList(true);
+
+ QString oldDtdNickName = DTDs::ref()->getDTDNickNameFromName(oldDtdName);
+ QString defaultDtdNickName = DTDs::ref()->getDTDNickNameFromName(defaultDocType);
+ for(uint i = 0; i < lst.count(); i++)
+ {
+ dtdWidget->dtdCombo->insertItem(lst[i]);
+ if (lst[i] == oldDtdNickName) pos = i;
+ if (lst[i] == defaultDtdNickName) defaultIndex = i;
+ }
+
+ if (pos == -1)
+ pos = defaultIndex;
+ dtdWidget->dtdCombo->setCurrentItem(pos);
+ dtdWidget->messageLabel->setText(i18n("Change the current DTD."));
+ dtdWidget->currentDTD->setText(DTDs::ref()->getDTDNickNameFromName(w->getDTDIdentifier()));
+ //dlg->useClosestMatching->setShown(false);
+ delete dtdWidget->useClosestMatching;
+ dtdWidget->useClosestMatching = 0L;
+ dtdWidget->adjustSize();
+ if (dlg.exec())
+ {
+ setDtep(dtdWidget->dtdCombo->currentText(), dtdWidget->convertDTD->isChecked());
+ }
+ }
+}
+
+void QuantaApp::slotEditDTD()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ QStringList lst(DTDs::ref()->nickNameList());
+ QString nickName = DTDs::ref()->getDTDNickNameFromName(w->getDTDIdentifier());
+ bool ok = false;
+ QString res = KInputDialog::getItem(
+ i18n( "Edit DTD" ),
+ i18n( "Please select a DTD:" ), lst, lst.findIndex(nickName), false, &ok, this );
+
+ QString s = i18n("Create a new DTEP description");
+ s = i18n("Load DTEP description from disk");
+ if (!ok)
+ return;
+
+ QString dtdName = DTDs::ref()->getDTDNameFromNickName(res);
+
+ KDialogBase editDlg(this, "edit_dtep", true, i18n("Configure DTEP"), KDialogBase::Ok | KDialogBase::Cancel);
+ DTEPEditDlg dtepDlg(DTDs::ref()->find(dtdName)->fileName, &editDlg);
+ editDlg.setMainWidget(&dtepDlg);
+ if (editDlg.exec())
+ {
+ dtepDlg.saveResult();
+ }
+ }
+}
+
+void QuantaApp::focusInEvent(QFocusEvent* e)
+{
+ KDockMainWindow::focusInEvent(e);
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ w->view()->setFocus();
+ w->checkDirtyStatus();
+ }
+}
+
+void QuantaApp::slotShowCompletion()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w && w->codeCompletionIf)
+ w->codeCompletionRequested();
+}
+
+void QuantaApp::slotShowCompletionHint()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w && w->codeCompletionIf)
+ w->codeCompletionHintRequested();
+}
+
+void QuantaApp::slotMakeDonation()
+{
+ DonationDialog *dlg = new DonationDialog(this);
+ dlg->closeButton->setIconSet(SmallIconSet("fileclose"));
+ connect(dlg->closeButton, SIGNAL(clicked()), dlg, SLOT(accept()));
+ dlg->exec();
+ delete dlg;
+}
+
+void QuantaApp::slotHelpHomepage()
+{
+ kapp->invokeBrowser("http://quanta.kdewebdev.org");
+}
+
+void QuantaApp::slotHelpUserList()
+{
+ kapp->invokeBrowser("http://mail.kde.org/mailman/listinfo/quanta");
+}
+
+/** Loads the toolbars for dtd named dtdName and unload the ones belonging to oldDtdName. */
+void QuantaApp::slotLoadToolbarForDTD(const QString& dtdName)
+{
+ const DTDStruct *oldDtd = 0L;
+
+ if (!currentToolbarDTD.isEmpty())
+ {
+ oldDtd = DTDs::ref()->find(currentToolbarDTD);
+ if (!oldDtd)
+ oldDtd = DTDs::ref()->find(Project::ref()->defaultDTD());
+ }
+ QString fileName;
+ const DTDStruct *newDtd = DTDs::ref()->find(dtdName);
+ if (!newDtd)
+ {
+ newDtd = DTDs::ref()->find(Project::ref()->defaultDTD());
+ if (!newDtd)
+ newDtd = DTDs::ref()->find(qConfig.defaultDocType); //extreme case
+ }
+
+ ToolbarEntry *p_toolbar;
+ if (m_debugger->UI())
+ {
+ p_toolbar = m_toolbarList["Debug"];
+ if (p_toolbar)
+ {
+ guiFactory()->removeClient(p_toolbar->guiClient);
+ p_toolbar->visible = false;
+ delete p_toolbar->menu;
+ p_toolbar->menu = 0L;
+ }
+ }
+ if (newDtd != oldDtd)
+ {
+ KURL::List newToolbars;
+ for (uint i = 0; i < newDtd->toolbars.count(); i++)
+ {
+ KURL url;
+ //first load the local version if it exists
+ fileName = locateLocal("data", resourceDir + "toolbars/"+newDtd->toolbars[i]);
+ QuantaCommon::setUrl(url, fileName);
+ if (QExtFileInfo::exists(url, true, this))
+ {
+ //showToolbarFile(url);
+ newToolbars += url;
+ } else
+ {
+ fileName = qConfig.globalDataDir + resourceDir + "toolbars/"+newDtd->toolbars[i];
+ QuantaCommon::setUrl(url, fileName);
+ if (QExtFileInfo::exists(url, true, this))
+ {
+ newToolbars += url;// showToolbarFile(url);
+ }
+ }
+ }
+ //remove the toolbars of the oldDtdName
+ if (!currentToolbarDTD.isEmpty())
+ {
+ for (uint i = 0; i < oldDtd->toolbars.count(); i++)
+ {
+ KURL url;
+ QString fileName = qConfig.globalDataDir + resourceDir + "toolbars/"+oldDtd->toolbars[i];
+ QuantaCommon::setUrl(url, fileName);
+ KURL urlLocal;
+ fileName = locateLocal("data", resourceDir + "toolbars/"+oldDtd->toolbars[i]);
+ QuantaCommon::setUrl(urlLocal, fileName);
+ if (newToolbars.contains(url) == 0)
+ {
+ QDictIterator<ToolbarEntry> iter(m_toolbarList);
+ for( ; iter.current(); ++iter )
+ {
+ p_toolbar = iter.current();
+ if (p_toolbar->url == url || p_toolbar->url == urlLocal)
+ {
+ guiFactory()->removeClient(p_toolbar->guiClient);
+ p_toolbar->visible = false;
+ delete p_toolbar->menu;
+ p_toolbar->menu = 0L;
+ break;
+ }
+ }
+ } else
+ {
+ newToolbars.remove(url);
+ }
+ }
+ }
+
+ //Load the toolbars for dtdName
+ KURL::List::Iterator it;
+ for (it = newToolbars.begin(); it != newToolbars.end(); ++it)
+ {
+ showToolbarFile(*it);
+ }
+ ToolbarTabWidget::ref()->setCurrentPage(0);
+ }
+ currentToolbarDTD = newDtd->name;
+ slotToggleDTDToolbar(!allToolbarsHidden());
+}
+
+/** Remove the toolbar named "name". */
+bool QuantaApp::slotRemoveToolbar(const QString& a_name)
+{
+ QString name = a_name; // increase reference counter for this string
+ ToolbarEntry *p_toolbar = m_toolbarList[name];
+ QRegExp i18ntabnameRx("\\si18ntabname=\"[^\"]*\"");
+ QRegExp idRx("\\sid=\"[^\"]*\"");
+ if (p_toolbar)
+ {
+ KXMLGUIClient* toolbarGUI = p_toolbar->guiClient;
+
+ if (toolbarGUI)
+ {
+ KAction *action;
+ //Rename the _Separator_ tags back to Separator, so they are not treated
+ //as changes
+ QDomNodeList nodeList = toolbarGUI->domDocument().elementsByTagName("_Separator_");
+ for (uint i = 0; i < nodeList.count(); i++)
+ {
+ nodeList.item(i).toElement().setTagName("Separator");
+ }
+ //check if the actions on the toolbar were modified or not
+ bool actionsModified = false;
+ nodeList = toolbarGUI->domDocument().elementsByTagName("Action");
+ for (uint i = 0; i < nodeList.count(); i++)
+ {
+ action = actionCollection()->action(nodeList.item(i).toElement().attribute("name"));
+ if (dynamic_cast<TagAction*>(action) &&
+ dynamic_cast<TagAction*>(action)->isModified())
+ {
+ actionsModified = true;
+ break;
+ }
+ }
+
+ //check if the toolbar's XML GUI was modified or not
+ QString s1 = p_toolbar->dom->toString();
+ QString s2 = toolbarGUI->domDocument().toString();
+ s1.remove(i18ntabnameRx);
+ s2.remove(i18ntabnameRx);
+ s1.remove(idRx);
+ s2.remove(idRx);
+ if (p_toolbar->nameModified)
+ {
+ QRegExp tabnameRx("\\stabname=\"[^\"]*\"");
+ tabnameRx.search(s2);
+ QString name1 = tabnameRx.cap();
+ name1.remove(" tab");
+ QString name2 = name1;
+ name2.remove(QRegExp("[\\s]\\([0-9]+\\)"));
+ s2.replace(name1, name2);
+ s2.replace(name1.lower(), name2.lower());
+ }
+ bool useToolbarGUI = true;
+ if ( s1 != s2 /*|| actionsModified */)
+ {
+ int result;
+ if (p_toolbar->url.isEmpty())
+ {
+ result = KMessageBox::warningYesNoCancel(this, i18n("<qt>Toolbar <b>%1</b> is new and unsaved. Do you want to save it before it is removed?</qt>").arg(p_toolbar->name),
+ i18n("Save Toolbar"), KStdGuiItem::save(), KStdGuiItem::discard());
+ } else
+ {
+ FourButtonMessageBox dlg(this, 0, true);
+ dlg.textLabel->setText(i18n("<qt>The toolbar <b>%1</b> was modified. Do you want to save it before it is removed?</qt>").arg(p_toolbar->name));
+ dlg.setCaption(i18n("Save Toolbar"));
+ dlg.pixmapLabel->setPixmap(BarIcon("messagebox_info", KIcon::SizeMedium));
+ dlg.exec();
+ result = dlg.status();
+ switch (result)
+ {
+ case -1: result = KMessageBox::Cancel;
+ break;
+ case 1: result = KMessageBox::Continue; //hack - this means Save
+ break;
+ case 2: result = KMessageBox::Yes; //hack - this means Save As
+ break;
+ case 3: result = KMessageBox::No; //this means Don't Save
+ break;
+ }
+ }
+ switch (result)
+ {
+ case KMessageBox::Yes:
+ {
+ bool local = true;
+ if (Project::ref()->hasProject() && p_toolbar->url.url().startsWith(Project::ref()->projectBaseURL().url())) local = false;
+ if (!saveToolbar(local, p_toolbar->id))
+ return false;
+ break;
+ }
+ case KMessageBox::Continue:
+ {
+ bool local = true;
+ if (Project::ref()->hasProject() && p_toolbar->url.url().startsWith(Project::ref()->projectBaseURL().url())) local = false;
+ if (!saveToolbar(local, p_toolbar->id, p_toolbar->url))
+ return false;
+ break;
+ }
+ case KMessageBox::No:
+ {
+ useToolbarGUI = false;
+ break;
+ }
+ case KMessageBox::Cancel: return false;
+
+ }
+ }
+
+ guiFactory()->removeClient(toolbarGUI);
+ delete p_toolbar->menu;
+//unplug the actions and remove them if they are not used in other places
+ if (useToolbarGUI)
+ nodeList = toolbarGUI->domDocument().elementsByTagName("Action");
+ else
+ nodeList = p_toolbar->dom->elementsByTagName("Action");
+ for (uint i = 0; i < nodeList.count(); i++)
+ {
+ action = actionCollection()->action(nodeList.item(i).toElement().attribute("name"));
+ if (action && !action->isPlugged())
+ {
+ if (dynamic_cast<TagAction*>(action) &&
+ !dynamic_cast<TagAction*>(action)->isModified())
+ {
+ //take out the action from every toolbar's xmlguiclient
+ //this avoid a crash when removing a toolbar
+ QDictIterator<ToolbarEntry> it(m_toolbarList);
+ while (it.current())
+ {
+ it.current()->guiClient->actionCollection()->take(action);
+ ++it;
+ }
+ delete action;
+ }
+ }
+ }
+ delete p_toolbar->dom;
+ delete p_toolbar->guiClient;
+ m_toolbarList.remove(name);
+ }
+ }
+
+ slotToggleDTDToolbar(!allToolbarsHidden());
+ emit toolbarRemoved(name);
+ return true;
+}
+
+/** Show or hide the DTD toolbar */
+void QuantaApp::slotToggleDTDToolbar(bool show)
+{
+ if (show)
+ {
+ ToolbarTabWidget::ref()->show();
+ } else
+ {
+ ToolbarTabWidget::ref()->hide();
+ }
+ qConfig.enableDTDToolbar = show;
+ if (ViewManager::ref()->activeView())
+ ViewManager::ref()->activeView()->refreshWindow();
+}
+
+void QuantaApp::slotRefreshActiveWindow()
+{
+//FIXME: Find a good way to redraw the editor view when the toolbar height
+//changes
+// if (ViewManager::ref()->activeView())
+ //ViewManager::ref()->activeView()->activated();
+}
+
+
+void QuantaApp::slotShowGroupsForDTEP(const QString& dtepName, bool show)
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ if (dtepName == "clear")
+ {
+ w->resetGroupsForDTEPList();
+ } else
+ {
+ w->enableGroupsForDTEP(dtepName, show);
+ }
+ w->setChanged(true);
+ reparse(false);
+ }
+}
+
+KURL QuantaApp::projectBaseURL() const
+{
+ return Project::ref()->projectBaseURL();
+}
+
+void QuantaApp::slotBuildPrjToolbarsMenu()
+{
+ static bool buildInProgress = false;
+ if (buildInProgress)
+ return;
+ KURL::List toolbarList;
+ if (Project::ref()->hasProject())
+ {
+ buildInProgress = true;
+ toolbarList = QExtFileInfo::allFiles(Project::ref()->toolbarURL(), "*"+toolbarExtension, this);
+ buildInProgress = false;
+ projectToolbarFiles->setMaxItems(toolbarList.count());
+ for (uint i = 0; i < toolbarList.count(); i++)
+ {
+ projectToolbarFiles->addURL(toolbarList[i]);
+ }
+ } else
+ {
+ projectToolbarFiles->clearURLList();
+ }
+}
+
+/** Returns the project (if there is one loaded) or global default encoding. */
+QString QuantaApp::defaultEncoding()
+{
+ QString encoding = qConfig.defaultEncoding;
+ if (Project::ref()->hasProject())
+ {
+ encoding = Project::ref()->defaultEncoding();
+ }
+ return encoding.lower();
+}
+
+void QuantaApp::slotGetUserToolbarFiles(KURL::List *list)
+{
+ ToolbarEntry *p_toolbar;
+ QDictIterator<ToolbarEntry> iter(m_toolbarList);
+ for( ; iter.current(); ++iter )
+ {
+ p_toolbar = iter.current();
+ if (p_toolbar->user && p_toolbar->visible)
+ {
+ list->append(p_toolbar->url);
+ }
+ }
+}
+
+ToolbarEntry *QuantaApp::toolbarByURL(const KURL& url)
+{
+ ToolbarEntry *p_toolbar = 0L;
+ QDictIterator<ToolbarEntry> iter(m_toolbarList);
+ for( ; iter.current(); ++iter )
+ {
+ p_toolbar = iter.current();
+ if (p_toolbar->url == url)
+ {
+ return p_toolbar;
+ }
+ }
+
+ return 0L;
+}
+
+
+/** Returns true if all toolbars are hidden, false otherwise. */
+bool QuantaApp::allToolbarsHidden() const
+{
+ bool result = true;
+ showDTDToolbar->setEnabled(false);
+ ToolbarEntry *p_toolbar = 0L;
+ QDictIterator<ToolbarEntry> iter(m_toolbarList);
+ for( ; iter.current(); ++iter )
+ {
+ p_toolbar = iter.current();
+ if (p_toolbar->visible)
+ {
+ showDTDToolbar->setEnabled(true);
+ result = false;
+ break;
+ }
+ }
+
+ if (!showDTDToolbar->isChecked())
+ result = true;
+ return result;
+}
+
+
+void QuantaApp::slotLoadDTEP()
+{
+ QString dirName = KFileDialog::getExistingDirectory(QString::null, 0, i18n("Select DTEP Directory"));
+ if (!dirName.isEmpty())
+ {
+ DTDs::ref()->slotLoadDTEP(dirName, true);
+ }
+}
+
+QString QuantaApp::createDTEPTarball()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ QStringList lst(DTDs::ref()->nickNameList());
+ QString nickName = DTDs::ref()->getDTDNickNameFromName(w->getDTDIdentifier());
+ bool ok = false;
+ QString res = KInputDialog::getItem(
+ i18n( "Send DTD" ),
+ i18n( "Please select a DTD:" ), lst, lst.findIndex(nickName), false, &ok, this );
+
+ if (!ok)
+ return QString::null;
+
+ QString dtdName = DTDs::ref()->getDTDNameFromNickName(res);
+
+ QString prefix="quanta";
+ KTempDir* tempDir = new KTempDir(tmpDir);
+ tempDir->setAutoDelete(true);
+ tempDirList.append(tempDir);
+ QString tempFileName=tempDir->name() +"/"+ DTDs::ref()->getDTDNickNameFromName(dtdName).replace(QRegExp("\\s|\\."), "_") + ".tgz";
+
+ //pack the .tag files and the description.rc into a .tgz file
+ KTar tar(tempFileName, "application/x-gzip");
+ tar.open(IO_WriteOnly);
+
+ KURL dirURL;
+ dirURL.setPath(DTDs::ref()->find(dtdName)->fileName);
+ dirURL.setPath(dirURL.directory(false));
+
+ KURL::List files = QExtFileInfo::allFilesRelative(dirURL, "*", this);
+ for ( KURL::List::Iterator it_f = files.begin(); it_f != files.end(); ++it_f )
+ {
+ QString name = (*it_f).fileName();
+
+ QFile file(dirURL.path()+name);
+ file.open(IO_ReadOnly);
+ QByteArray bArray = file.readAll();
+ tar.writeFile(dirURL.fileName()+"/"+name, "user", "group", bArray.size(), bArray.data());
+ file.close();
+
+ }
+ tar.close();
+ return tempFileName;
+ }
+ return QString::null;
+}
+
+void QuantaApp::slotEmailDTEP()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ QString tempFileName = createDTEPTarball();
+ if (tempFileName.isNull())
+ return;
+ QStringList dtdFile;
+ dtdFile += tempFileName;
+
+ TagMailDlg *mailDlg = new TagMailDlg( this, i18n("Send DTEP in Email"));
+ QString toStr;
+ QString message = i18n("Hi,\n This is a Quanta Plus [http://quanta.kdewebdev.org] DTEP definition tarball.\n\nHave fun.\n");
+ QString titleStr;
+ QString subjectStr;
+
+ mailDlg->TitleLabel->setText(i18n("Content:"));
+/* mailDlg->titleEdit->setFixedHeight(60);
+ mailDlg->titleEdit->setVScrollBarMode(QTextEdit::Auto);
+ mailDlg->titleEdit->setHScrollBarMode(QTextEdit::Auto);*/
+ if ( mailDlg->exec() )
+ {
+ if ( !mailDlg->lineEmail->text().isEmpty())
+ {
+ toStr = mailDlg->lineEmail->text();
+ subjectStr = (mailDlg->lineSubject->text().isEmpty())?i18n("Quanta Plus DTD"):mailDlg->lineSubject->text();
+ if ( !mailDlg->titleEdit->text().isEmpty())
+ message = mailDlg->titleEdit->text();
+ } else
+ {
+ KMessageBox::error(this,i18n("No destination address was specified.\n Sending is aborted."),i18n("Error Sending Email"));
+ delete mailDlg;
+ return;
+ }
+
+ kapp->invokeMailer(toStr, QString::null, QString::null, subjectStr, message, QString::null, dtdFile);
+ }
+ delete mailDlg;
+ }
+}
+
+void QuantaApp::slotDownloadDTEP()
+{
+ if (!m_newDTEPStuff)
+ m_newDTEPStuff = new QNewDTEPStuff("quanta/dtep", this);
+ m_newDTEPStuff->downloadResource();
+}
+
+void QuantaApp::slotUploadDTEP()
+{
+ QString tempFileName = createDTEPTarball();
+ if (tempFileName.isNull())
+ return;
+ if (!m_newDTEPStuff)
+ m_newDTEPStuff = new QNewDTEPStuff("quanta/dtep", this);
+// tempDirList.append(m_newDTEPStuff->uploadResource(tempFileName));
+ m_newDTEPStuff->uploadResource(tempFileName);
+}
+
+void QuantaApp::slotSmartTagInsertion()
+{
+ KAction *action = actionCollection()->action("smart_tag_insertion");
+ if(!action)
+ return;
+ if(!ViewManager::ref()->activeDocument() || !ViewManager::ref()->activeView() ||
+ ViewManager::ref()->activeDocument()->defaultDTD()->name.contains("HTML", false) == 0)
+ {
+ KMessageBox::error(this, "Smart Tag Insertion is available only for (X)HTML for the moment.");
+ qConfig.smartTagInsertion = false;
+ (static_cast<KToggleAction* >(action))->setChecked(false);
+ return;
+ }
+ qConfig.smartTagInsertion = (static_cast<KToggleAction* >(action))->isChecked();
+}
+
+void QuantaApp::slotDownloadTemplate()
+{
+ if (!m_newTemplateStuff)
+ m_newTemplateStuff = new QNewTemplateStuff("quanta/template", this);
+ m_newTemplateStuff->downloadResource();
+}
+
+void QuantaApp::slotUploadTemplate(const QString &fileName)
+{
+ if (!m_newTemplateStuff)
+ m_newTemplateStuff = new QNewTemplateStuff("quanta/template", this);
+// tempDirList.append(m_newTemplateStuff->uploadResource(fileName));
+ m_newTemplateStuff->uploadResource(fileName);
+}
+
+void QuantaApp::slotDownloadScript()
+{
+ if (!m_newScriptStuff)
+ m_newScriptStuff = new QNewScriptStuff("quanta/script", this);
+ m_newScriptStuff->downloadResource();
+}
+
+void QuantaApp::slotUploadScript(const QString &fileName)
+{
+ if (!m_newScriptStuff)
+ m_newScriptStuff = new QNewScriptStuff("quanta/script", this);
+// tempDirList.append(m_newScriptStuff->uploadResource(fileName));
+ m_newScriptStuff->uploadResource(fileName);
+}
+
+void QuantaApp::slotDownloadDoc()
+{
+ if (!m_newDocStuff)
+ {
+ m_newDocStuff = new QNewDocStuff("quanta/documentation", this);
+ connect(m_newDocStuff, SIGNAL(installFinished()), dTab, SLOT(slotRefreshTree()));
+ }
+ m_newDocStuff->downloadResource();
+}
+
+void QuantaApp::slotCodeFormatting()
+{
+ QuantaView *view = ViewManager::ref()->activeView();
+ if(!view || !view->document() || (view->currentViewsLayout() != QuantaView::SourceOnly &&
+ view->hadLastFocus() == QuantaView::VPLFocus))
+ {
+ KMessageBox::error(this, i18n("Code formatting can only be done in the source view."));
+ return;
+ }
+ view->document()->docUndoRedo->codeFormatting();
+}
+
+void QuantaApp::slotDocumentProperties()
+{
+ documentProperties(false);
+}
+
+void QuantaApp::documentProperties(bool forceInsertionOfMinimalTree)
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ if (w->defaultDTD()->name.contains("HTML", false) == 0)
+ {
+ KMessageBox::information(this, i18n("The Document Properties Dialog is only for HTML and XHTML."));
+ return;
+ }
+ htmlDocumentProperties htmlPropsDlg(this, forceInsertionOfMinimalTree);
+ htmlPropsDlg.exec();
+ w->setModified(true);
+ }
+}
+
+/** Returns the interface number for the currently active editor. */
+int QuantaApp::currentEditorIfNum() const
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ return w->editIf->editInterfaceNumber();
+ } else
+ {
+ QuantaView * view = ViewManager::ref()->lastActiveEditorView();
+ if (view)
+ return view->document()->editIf->editInterfaceNumber();
+ else
+ return 0L;
+ }
+}
+
+QString QuantaApp::projectURL() const
+{
+ return Project::ref()->projectBaseURL().url();
+}
+
+QStringList QuantaApp::openedURLs() const
+{
+ QStringList list;
+ QPtrListIterator<KMdiChildView> childIt(*m_pDocumentViews);
+ KMdiChildView *view;
+ QuantaView *qView;
+ while ( (view = childIt.current()) != 0 )
+ {
+ ++childIt;
+ qView = dynamic_cast<QuantaView*>(view);
+ if (qView)
+ {
+ Document *w = qView->document();
+ if ( w )
+ {
+ list.prepend( QString("%1:%2").arg(w->editIf->editInterfaceNumber()).arg(w->url().url()));
+ }
+ }
+ }
+
+ return list;
+}
+
+void QuantaApp::slotExpandAbbreviation()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ const DTDStruct *dtd = w->currentDTD();
+ uint line, col;
+ w->viewCursorIf->cursorPositionReal(&line, &col);
+ QString text = w->text(line, 0, line, col - 1);
+ text = w->findWordRev(text) + " ";
+ QString textToInsert;
+ QMap<QString, Abbreviation>::ConstIterator it;
+ for (it = qConfig.abbreviations.constBegin(); it != qConfig.abbreviations.constEnd(); ++it)
+ {
+ bool found = false;
+ Abbreviation abbrev = it.data();
+ if (abbrev.dteps.contains(dtd->name))
+ {
+ QMap<QString, QString>::ConstIterator it2;
+ for (it2 = abbrev.abbreviations.constBegin(); it2 != abbrev.abbreviations.constEnd(); ++it2)
+ {
+ if (it2.key().startsWith(text))
+ {
+ textToInsert = it2.data();
+ found = true;
+ break;
+ }
+ }
+ }
+ if (found)
+ break;
+ }
+ if (!textToInsert.isEmpty())
+ {
+ w->activateParser(false);
+ w->editIf->removeText(line, col - text.length() + 1, line, col);
+ w->activateParser(true);
+ col -= (text.length() - 1);
+ int pos = textToInsert.find('|');
+ if (pos != -1)
+ {
+ text = textToInsert.left(pos);
+ if (text.contains('\n'))
+ {
+ line += text.contains('\n');
+ col = text.length() - text.findRev('\n') - 1;
+ } else
+ {
+ col += pos;
+ }
+ }
+ textToInsert.replace('|',"");
+ w->insertText(textToInsert, false);
+ w->viewCursorIf->setCursorPositionReal(line, col);
+ }
+ }
+}
+
+void QuantaApp::slotUploadFile(QuantaView *view)
+{
+ if (!view)
+ view = ViewManager::ref()->activeView();
+ bool quick = true;
+ if (KMessageBox::questionYesNo(this, i18n("Do you want to review the upload?"), i18n("Enable Quick Upload"), i18n("Review"), i18n("Do Not Review"), "EnableQuickUpload") == KMessageBox::Yes)
+ quick = false;
+ Project::ref()->slotUploadURL(view->document()->url(), "", quick, false);
+}
+
+
+void QuantaApp::slotUploadOpenedFiles()
+{
+}
+
+void QuantaApp::slotDeleteFile(QuantaView *view)
+{
+ if (!view)
+ view = ViewManager::ref()->activeView();
+ Document *w = view->document();
+ KURL url = w->url();
+ bool modified = w->isModified();
+ w->setModified(false); //don't ask for save
+ if (QuantaNetAccess::del(url, this, true))
+ {
+ ViewManager::ref()->removeView(view);
+ } else
+ w->setModified(modified);
+}
+
+
+bool QuantaApp::structTreeVisible() const
+{
+ return StructTreeView::ref()->isVisible();
+}
+
+QStringList QuantaApp::tagAreas(const QString &tag, bool includeCoordinates, bool skipFoundContent) const
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ return w->tagAreas(tag, includeCoordinates, skipFoundContent);
+ else
+ return QStringList();
+}
+
+QString QuantaApp::documentFolderForURL(const QString &url)
+{
+ KURL u = KURL::fromPathOrURL(url);
+ return Project::ref()->documentFolderForURL(u).url();
+}
+
+QString QuantaApp::urlWithPreviewPrefix(const QString &url)
+{
+ KURL u = KURL::fromPathOrURL(url);
+ return Project::ref()->urlWithPrefix(u).url();
+}
+
+void QuantaApp::addFileToProject(const QString &url)
+{
+ if (Project::ref()->hasProject())
+ {
+ Project::ref()->slotInsertFile(KURL::fromPathOrURL(url));
+ }
+}
+
+void QuantaApp::addFolderToProject(const QString &url)
+{
+ if (Project::ref()->hasProject())
+ {
+ Project::ref()->slotAddDirectory(KURL::fromPathOrURL(url), true);
+ }
+}
+
+void QuantaApp::uploadURL(const QString &url, const QString& profile, bool markOnly)
+{
+ if (Project::ref()->hasProject())
+ {
+ Project::ref()->slotUploadURL(url, profile, true, markOnly);
+ }
+}
+
+void QuantaApp::slotAutosaveTimer()
+{
+ m_config->reparseConfiguration();
+ QPtrListIterator<KMdiChildView> childIt(*m_pDocumentViews);
+ KMdiChildView *view;
+ QuantaView *qView;
+ while ( (view = childIt.current()) != 0 )
+ {
+ ++childIt;
+ qView = dynamic_cast<QuantaView*>(view);
+ if (qView)
+ {
+ Document *w = qView->document();
+ if ( w )
+ {
+ w->createBackup(m_config);
+ }
+ }
+ }
+
+}
+
+/** Get script output */
+void QuantaApp::slotGetScriptOutput(KProcess* ,char* buf,int buflen)
+{
+ QCString tmp( buf, buflen + 1 );
+ m_scriptOutput = QString::null;
+ m_scriptOutput = QString::fromLocal8Bit(tmp).remove(" ");
+}
+
+/** Get script error*/
+void QuantaApp::slotGetScriptError(KProcess* ,char* buf,int buflen)
+{
+//TODO: Implement some error handling?
+ Q_UNUSED(buf);
+ Q_UNUSED(buflen);
+}
+/** Notify when process exits*/
+void QuantaApp::slotProcessExited(KProcess* process)
+{
+ slotProcessTimeout();
+ delete process;
+}
+
+/** Timeout occurred while waiting for some network function to return. */
+void QuantaApp::slotProcessTimeout()
+{
+ if (m_loopStarted)
+ {
+ qApp->exit_loop();
+ m_loopStarted = false;
+ }
+}
+
+void QuantaApp::slotActivePartChanged(KParts::Part * part)
+{
+ if (m_oldKTextEditor && part) // if part == 0L the pointer m_oldKTextEditor is not useable
+ {
+ guiFactory()->removeClient(m_oldKTextEditor);
+ m_oldKTextEditor = 0L;
+ }
+ createGUI(part);
+ QWidget * activeWid = m_partManager->activeWidget();
+ if ( activeWid && activeWid->inherits("KTextEditor::View"))
+ {
+ m_oldKTextEditor = dynamic_cast<KTextEditor::View *>(activeWid);
+ if (m_oldKTextEditor)
+ guiFactory()->addClient(m_oldKTextEditor);
+ }
+}
+
+void QuantaApp::slotConvertCase()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ w->convertCase();
+ }
+}
+
+void QuantaApp::slotReloadStructTreeView(bool groupOnly)
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (StructTreeView::ref()->isVisible() && w)
+ {
+ StructTreeView::ref()->setParsingDTDs(w->groupsForDTEPs());
+ int expandLevel = qConfig.expandLevel;
+ if (expandLevel == 0)
+ expandLevel = 40;
+ StructTreeView::ref()->slotReparse(w, baseNode, expandLevel, groupOnly);
+ } else
+ StructTreeView::ref()->slotReparse(0L, 0L, 0); //delete the tree
+
+ if (!groupOnly && w)
+ {
+ m_annotationOutput->clearAnnotations();
+ w->clearAnnotations();
+ Node *node = baseNode;
+ while (node)
+ {
+ if (node->tag->type == Tag::Comment)
+ {
+ Node *n = node;
+ if (node->child)
+ {
+ n = node->child;
+ }
+ Tag *commentTag = n->tag;
+ QString text = commentTag->tagStr();
+ int pos = text.find("@annotation");
+ if (pos != -1)
+ {
+ pos += 11;
+ QString receiver;
+ if (text[pos] == '(')
+ {
+ int p = pos;
+ pos = text.find(')');
+ if (pos != -1)
+ {
+ receiver = text.mid(p + 1, pos - p - 1);
+ pos += 2;
+ }
+ } else
+ pos++;
+ text = text.mid(pos).stripWhiteSpace();
+ int l, c;
+ if (n->next)
+ n->next->tag->beginPos(l, c);
+ else
+ n->tag->endPos(l, c);
+ commentTag->write()->addAnnotation(l, qMakePair(text, receiver));
+ }
+ }
+ node = node->nextSibling();
+ }
+ }
+}
+
+QString QuantaApp::saveCurrentFile()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w)
+ return QString::null;
+ if (w->isModified())
+ {
+ if ( KMessageBox::questionYesNo(this,
+ i18n("The file must be saved before external preview.\n"
+ "Do you want to save and preview?"),
+ i18n("Save Before Preview"),
+ KStdGuiItem::save(),KStdGuiItem::dontSave(), "AskForSaveBeforePreview")
+ == KMessageBox::Yes)
+ {
+ if (w->isUntitled())
+ {
+ quantaApp->slotFileSaveAs();
+ }
+ else
+ {
+ w->save();
+ }
+ } else
+ {
+ return QString::null;
+ }
+ }
+ KURL url = Project::ref()->urlWithPrefix(w->url());
+ return url.url();
+}
+
+void QuantaApp::slotReportBug()
+{
+ KAboutData aboutData( "quanta", I18N_NOOP("Quanta"), QUANTA_VERSION);
+ KBugReport bugReportDlg(this, true, &aboutData);
+ bugReportDlg.exec();
+}
+
+void QuantaApp::slotNewPart(KParts::Part *newPart, bool setActiv)
+{
+ m_partManager->addPart(newPart, setActiv);
+}
+
+
+bool QuantaApp::queryClose()
+{
+ if (m_quantaInit)
+ return false; //not loaded completely
+ bool canExit = true;
+ if (quantaStarted)
+ {
+ m_config->setGroup("General Options");
+ QStringList urlStrList;
+ KURL::List urlList = ViewManager::ref()->openedFiles();
+ KURL u;
+ for (KURL::List::Iterator it = urlList.begin(); it != urlList.end(); ++it)
+ {
+ KURL u = *it;
+ u.setPass("");
+ urlStrList += u.url();
+ }
+ m_config->writePathEntry("List of opened files", urlStrList);
+ QStringList encodings;
+ QValueList<Document*> documents = ViewManager::ref()->openedDocuments();
+ for (QValueList<Document*>::ConstIterator it = documents.constBegin(); it != documents.constEnd(); ++it)
+ {
+ if (!(*it)->isUntitled())
+ {
+ QString encoding = defaultEncoding();
+ KTextEditor::EncodingInterface* encodingIf = dynamic_cast<KTextEditor::EncodingInterface*>((*it)->doc());
+ if (encodingIf)
+ encoding = encodingIf->encoding();
+ if (encoding.isEmpty())
+ encoding = "utf8"; //final fallback
+ encodings += encoding;
+ }
+ }
+ m_config->writePathEntry("Encoding of opened files", encodings);
+ parser->setParsingEnabled(false);
+ canExit = ViewManager::ref()->closeAll(false);
+ if (canExit)
+ canExit = Project::ref()->queryClose();
+ if (canExit)
+ canExit = removeToolbars();
+ parser->setParsingEnabled(true);
+ }
+ if (canExit)
+ {
+ saveOptions();
+ // kdDebug(24000) << "Quanta will exit" << endl;
+ emit eventHappened("quanta_exit", QDateTime::currentDateTime().toString(Qt::ISODate), QString::null);
+ } else
+ slotFileNew();
+ return canExit;
+}
+
+void QuantaApp::saveOptions()
+{
+ if (m_config)
+ {
+ m_config->setGroup ("General Options");
+
+ m_config->writeEntry("Geometry", size());
+
+ m_config->writeEntry("Show Toolbar", toolBar("mainToolBar")->isVisible());
+ m_config->writeEntry("Show DTD Toolbar", showDTDToolbar->isChecked());
+
+ m_config->writeEntry("Markup mimetypes", qConfig.markupMimeTypes );
+ m_config->writeEntry("Script mimetypes", qConfig.scriptMimeTypes );
+ m_config->writeEntry("Image mimetypes", qConfig.imageMimeTypes );
+ m_config->writeEntry("Text mimetypes", qConfig.textMimeTypes );
+
+ m_config->writeEntry("Capitals for tags", qConfig.tagCase);
+ m_config->writeEntry("Capitals for attr", qConfig.attrCase);
+ m_config->writeEntry("Attribute quotation", qConfig.attrValueQuotation=='"' ? "double":"single");
+ m_config->writeEntry("Close tag if optional", qConfig.closeOptionalTags);
+ m_config->writeEntry("Close tags", qConfig.closeTags);
+ m_config->writeEntry("Auto completion", qConfig.useAutoCompletion);
+ m_config->writeEntry("Update Closing Tags", qConfig.updateClosingTags);
+ m_config->writeEntry("Replace Accented Chars", qConfig.replaceAccented);
+ m_config->writeEntry("Replace Chars Not In Current Encoding", qConfig.replaceNotInEncoding);
+
+ m_config->writeEntry("Default encoding", qConfig.defaultEncoding);
+ m_config->writeEntry("Default DTD", qConfig.defaultDocType);
+
+ m_config->writeEntry("Preview area", qConfig.previewPosition);
+ m_config->writeEntry("Documentation area", qConfig.docPosition);
+
+ m_config->writeEntry("Smart Tag Insertion", qConfig.smartTagInsertion);
+
+ m_config->writeEntry("Window layout", qConfig.windowLayout);
+ m_config->writeEntry("Follow Cursor", StructTreeView::ref()->followCursor() );
+ //If user choose the timer interval, it needs to restart the timer too
+ m_config->writeEntry("Autosave interval", qConfig.autosaveInterval);
+ m_config->writePathEntry("Top folders", fTab->topURLList.toStringList());
+ QStringList aliasList;
+ for (KURL::List::Iterator it2 = fTab->topURLList.begin(); it2 != fTab->topURLList.end(); ++it2)
+ {
+ aliasList.append(fTab->topURLAliases[(*it2).url()]);
+ }
+ m_config->writePathEntry("Top folder aliases", aliasList);
+ m_config->writeEntry("Version", QUANTA_VERSION); // version
+ m_config->writeEntry("Close Buttons", qConfig.showCloseButtons);
+ m_config->writeEntry("MDI mode", mdiMode());
+ m_config->writeEntry("MDI style", qConfig.toolviewTabs);
+ m_config->writeEntry("IconTextMode", ToolbarTabWidget::ref()->iconText());
+
+ m_config->deleteGroup("RecentFiles");
+ fileRecent->saveEntries(m_config);
+ m_config->writeEntry("Show Hidden Files", qConfig.showHiddenFiles);
+ m_config->writeEntry("Save Local Trees", qConfig.saveTrees);
+
+ m_config->setGroup("Parser options");
+ m_config->writeEntry("Instant Update", qConfig.instantUpdate);
+ m_config->writeEntry("Show Empty Nodes", qConfig.showEmptyNodes);
+ m_config->writeEntry("Show Closing Tags", qConfig.showClosingTags);
+ m_config->writeEntry("Refresh frequency", qConfig.refreshFrequency);
+ m_config->writeEntry("Expand Level", qConfig.expandLevel);
+ m_config->writeEntry("Show DTD Select Dialog", qConfig.showDTDSelectDialog);
+
+ manager()->writeConfig(m_config);
+ saveMainWindowSettings(m_config);
+ writeDockConfig(m_config);
+ // save settings of treeviews
+ fTab->saveLayout( m_config, fTab->className() );
+ ProjectTreeView::ref()->saveLayout(m_config, ProjectTreeView::ref()->className() );
+ TemplatesTreeView::ref()->saveLayout(m_config, TemplatesTreeView::ref()->className() );
+ scriptTab->saveLayout(m_config, scriptTab->className() );
+
+ m_config->sync();
+ }
+}
+
+void QuantaApp::statusBarTimeout()
+{
+ statusBar()->changeItem("", IDS_STATUS);
+}
+
+QStringList QuantaApp::selectors(const QString &tag)
+{
+ return dcopQuanta->selectors(tag);
+}
+
+QStringList QuantaApp::idSelectors()
+{
+ return dcopQuanta->idSelectors();
+}
+
+void QuantaApp::slotEditCurrentTag()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+ if (parser->parsingNeeded())
+ baseNode = parser->rebuild(w);
+ //avoid reparsing while the dialog is shown
+ typingInProgress = true;
+ slotEnableIdleTimer(false);
+ uint line,col;
+ w->viewCursorIf->cursorPositionReal(&line, &col);
+ Node *node = parser->nodeAt(line, col, false);
+ bool isUnknown = true;
+ QString tagName;
+ if (node && node->tag)
+ {
+ Tag *tag = new Tag(*node->tag); //create a copy, as a reparse might happen meantime and that would make node (and node->tag) invalid
+ tagName = tag->name;
+ if ( QuantaCommon::isKnownTag(tag->dtd()->name,tagName) )
+ {
+ isUnknown = false;
+ QString selection;
+ if (w->selectionIf)
+ selection = w->selectionIf->selection();
+ TagDialog *dlg = new TagDialog( QuantaCommon::tagFromDTD(tag->dtd(),tagName), tag, selection, ViewManager::ref()->activeView()->baseURL() );
+ if (dlg->exec())
+ {
+ w->changeTag(tag, dlg->getAttributes() );
+ }
+ delete tag;
+ delete dlg;
+ }
+ }
+ if (isUnknown)
+ {
+ const DTDStruct *dtd = w->defaultDTD();
+ if (dtd->family == Xml)
+ {
+ QString currentLine = w->editIf->textLine(line);
+ int sPos = currentLine.findRev('<', col);
+ if (sPos != -1)
+ {
+ int ePos = currentLine.find('>', col);
+ if (ePos != -1)
+ {
+ AreaStruct area(line, sPos, line, ePos);
+ Tag *tag = new Tag(area, w, dtd, true);
+ if ( QuantaCommon::isKnownTag(dtd->name, tag->name) )
+ {
+ isUnknown = false;
+ QString selection;
+ if (w->selectionIf)
+ selection = w->selectionIf->selection();
+ TagDialog *dlg = new TagDialog( QuantaCommon::tagFromDTD(dtd, tag->name), tag, selection, ViewManager::ref()->activeView()->baseURL() );
+ if (dlg->exec())
+ {
+ w->changeTag(tag, dlg->getAttributes() );
+ }
+ delete dlg;
+ }
+ delete tag;
+ }
+ }
+ }
+ }
+ typingInProgress = false;
+ slotEnableIdleTimer(true);
+ if (isUnknown)
+ {
+ QString message = i18n("Unknown tag: %1").arg(tagName);
+ slotStatusMsg( message );
+ }
+}
+
+void QuantaApp::slotSelectTagArea(Node *node)
+{
+ int bLine, bCol, eLine, eCol;
+ Tag *tag = node->tag;
+ tag->beginPos(bLine, bCol);
+ if (tag->single || !node->next)
+ {
+ tag->endPos(eLine, eCol);
+ } else
+ if (tag->closingMissing && node->child)
+ {
+ Node *childNode = node->child;
+ while (childNode->child || childNode->next)
+ {
+ if (childNode->next)
+ {
+ childNode = childNode->next;
+ } else
+ {
+ childNode = childNode->child;
+ }
+ }
+ childNode->tag->endPos(eLine, eCol);
+ } else
+ {
+ node->next->tag->endPos(eLine, eCol);
+ }
+ quantaApp->selectArea(bLine, bCol, eLine, eCol + 1);
+}
+
+void QuantaApp::slotSelectTagArea()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w)
+ return;
+ uint line,col;
+ w->viewCursorIf->cursorPositionReal(&line, &col);
+ Node *node = parser->nodeAt(line, col);
+ slotSelectTagArea(node);
+}
+
+void QuantaApp::slotFrameWizard()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w)
+ return;
+ QStringList list = w->tagAreas("frameset", true, true);
+ bool framesetExists = !list.isEmpty();
+ int bl, bc, el, ec;
+ bl = bc = el = ec = 0;
+ QStringList l;
+ QStringList l2;
+ QuantaCommon::normalizeStructure(list[0],l2);
+ if (framesetExists)
+ {
+ l = QStringList::split('\n',list[0],true);
+ QStringList coordList = QStringList::split(',', l[0], true);
+ bl = coordList[0].toInt();
+ bc = coordList[1].toInt();
+ el = coordList[2].toInt();
+ ec = coordList[3].toInt();
+ l.remove(l.begin());
+ }
+
+ FrameWizard dlg(this);
+
+ if (!w->isUntitled())
+ {
+ dlg.setSaved(true);
+ }
+ dlg.setMarkupLanguage(w->currentDTD(true)->name);
+ dlg.loadExistingFramesetStructure(l2);
+
+ if ( dlg.exec() )
+ {
+ QString tag =
+QString("\n")+dlg.generateFramesetStructure()+QString("\n");
+ if (framesetExists)
+ {
+ w->activateParser(false);
+ w->editIf->removeText(bl, bc, el, ec + 1);
+ w->viewCursorIf->setCursorPositionReal((uint)bl, (uint)bc);
+ w->activateParser(true);
+ }
+ w->insertTag(tag);
+ }
+}
+
+
+/** edit/insert CSS */
+void QuantaApp::slotInsertCSS()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+
+ uint line, col;
+ int bLine, bCol, eLine, eCol;
+ bLine = bCol = eLine = eCol = 0;
+ w->viewCursorIf->cursorPositionReal(&line, &col);
+ if (line == 0 && col == 0)
+ col++;
+ parser->rebuild(w);
+ Node *node = parser->nodeAt(line, col, false);
+ unsigned int lastLine = w->editIf->numLines() - 1;
+ unsigned int lastCol = w->editIf->lineLength(lastLine);
+ Node *styleNode = node;
+
+ if (styleNode->tag->type == Tag::XmlTagEnd && styleNode->prev)
+ styleNode = styleNode->prev;
+
+ while (styleNode && styleNode->parent && styleNode->tag->name.lower() != "style" && styleNode->tag->dtd()->name == "text/css")
+ styleNode = styleNode->parent;
+
+ Node *parentNode = node;
+ if (parentNode->tag->type == Tag::XmlTagEnd && parentNode->prev)
+ parentNode = parentNode->prev;
+ else
+ while (parentNode && parentNode->parent &&
+ parentNode->tag->type != Tag::XmlTag)
+ parentNode = parentNode->parent;
+ QString fullDocument = w->editIf->text().stripWhiteSpace();
+
+ if (styleNode->tag->name.lower() == "comment block" && styleNode->parent) {
+ if (styleNode->parent->tag->name.lower() == "style") {
+ styleNode = styleNode->parent;
+ }
+ }
+
+ if (styleNode && styleNode->tag->name.lower() == "style" && styleNode->next) //inside <style> invoke the selector editor
+ {
+ styleNode->tag->endPos(bLine, bCol);
+ QString header(w->text(0, 0, bLine, bCol));// beginning part of the file
+ styleNode->next->tag->endPos(eLine, eCol);
+ QString footer("</style>" + w->text(eLine, eCol+1, lastLine, lastCol)); // ending part of the file
+
+ styleNode->next->tag->beginPos(eLine, eCol);
+ QString styleTagContent(w->text(bLine, bCol+1, eLine, eCol-1).remove("<!--").remove("-->"));// <style></style> block content
+ kdDebug(24000) << "Style tag contains: " << endl << styleTagContent << endl;
+ CSSSelector *dlg = new CSSSelector;
+
+ dlg->setCallingFrom("XHTML");
+ QFileInfo fi(ViewManager::ref()->currentURL());
+ dlg->setFileToPreview(projectBaseURL().path() + fi.baseName());
+
+
+ dlg->setHeader(header);
+ dlg->setFooter(footer);
+
+ dlg->loadCSSContent(styleTagContent);
+ if(!dlg->errorOnProcessingStylesheet())
+ if( dlg->exec() ){
+ w->activateParser(false);
+ w->editIf->removeText(bLine, bCol+1, eLine, eCol);
+ w->viewCursorIf->setCursorPositionReal((uint)bLine, (uint)bCol+1);
+ w->activateParser(true);
+ w->insertTag( /*"\n<!--" + */ dlg->generateFormattedStyleSection() /*+ "-->\n"*/);
+ }
+ delete dlg;
+
+ } else
+ if (!node || w->currentDTD(true)->name == "text/css")
+ {
+ kdDebug(24000) << "[CSS editor] This is a pure CSS document" << endl;
+
+ CSSSelector *dlg = new CSSSelector;
+
+ dlg->setCallingFrom("CSS");
+
+ if (!fullDocument.isEmpty())
+ dlg->loadCSSContent(fullDocument);
+ dlg->enableApplyToFile();
+ if(!dlg->errorOnProcessingStylesheet())
+ if (dlg->exec())
+ {
+ w->activateParser(false);
+ w->editIf->clear();
+ w->activateParser(true);
+ w->insertTag(dlg->generateFormattedStyleSection());
+ }
+ delete dlg;
+ } else
+ if (parentNode && parentNode->tag->type == Tag::XmlTag)
+ {
+ kdDebug(24000) << "[CSS editor] We will add a style attribute to: " << parentNode->tag->name << endl;
+ CSSEditor *dlg = new CSSEditor(this);
+ QFileInfo fi(ViewManager::ref()->currentURL());
+ dlg->setFileToPreview(projectBaseURL().path() + fi.baseName(),false);
+
+
+ parentNode->tag->beginPos(bLine, bCol);
+ parentNode->tag->endPos(eLine, eCol);
+ dlg->setFooter(">" + w->text(eLine, eCol + 1, lastLine, lastCol));
+
+ QString temp;
+ if (parentNode->tag->hasAttribute("style"))
+ {
+ dlg->setInlineStyleContent(parentNode->tag->attributeValue("style"));
+ Tag tempTag(*(parentNode->tag));
+ tempTag.deleteAttribute("style");
+ temp = tempTag.toString();
+
+ } else {
+ dlg->setInlineStyleContent(QString::null);
+ temp = parentNode->tag->toString();
+ }
+ //using QString::mid sometimes generates strange results; maybe this is due to a (random) blank in temp
+ temp = temp.left(temp.length()-1);//remove >
+ temp = temp.right(temp.length()-1);//remove <
+ dlg->setHeader(w->text(0, 0, bLine, bCol) + temp);
+
+ dlg->initialize();
+ if( dlg->exec() )
+ {
+ w->changeTagAttribute(parentNode->tag, "style", dlg->generateProperties());
+ }
+ delete dlg;
+ } else
+ KMessageBox::sorry(this, i18n("The CSS Editor cannot be invoked here.\nTry to invoke it on a tag or on a style section."));
+}
+
+/** for <a href=mailto> tag */
+void QuantaApp::slotTagMail()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+
+ TagMailDlg *mailDlg = new TagMailDlg( this, i18n("Email Link (mailto)"));
+
+ if ( mailDlg->exec() ) {
+ QString tag = QString(QuantaCommon::tagCase("<a"));
+
+ if ( !QString(mailDlg->lineEmail->text()).isEmpty())
+ {
+ tag += QuantaCommon::attrCase(" href=")+qConfig.attrValueQuotation+"mailto:"+mailDlg->lineEmail->text();
+ if ( !QString(mailDlg->lineSubject->text()).isEmpty())
+ tag += "?subject="+KURL::encode_string(mailDlg->lineSubject->text());
+ tag += qConfig.attrValueQuotation;
+ }
+
+ if ( !QString(mailDlg->titleEdit->text()).isEmpty())
+ tag += QuantaCommon::attrCase(" title=")+qConfig.attrValueQuotation+mailDlg->titleEdit->text()+qConfig.attrValueQuotation;
+ tag += QString(">");
+ w->insertTag(tag,QuantaCommon::tagCase("</a>"));
+ }
+ delete mailDlg;
+}
+
+/** Add the starting and closing text for a
+user specified tag. */
+void QuantaApp::slotTagMisc()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+
+ static QString element = "";
+ static bool addClosingTag = true;
+
+ TagMiscDlg * miscDlg = new TagMiscDlg( this, 0L, addClosingTag, element );
+
+ if ( miscDlg->exec() )
+ {
+ QString tag;
+ element = miscDlg->elementTagName();
+ element.remove('<');
+ element.remove('>');
+ if ( !element.isEmpty())
+ {
+ tag += "<" + QuantaCommon::attrCase(element)+">";
+ if ( (addClosingTag = miscDlg->addClosingTag()) == true)
+ {
+ w->insertTag(tag,QuantaCommon::tagCase( "</"+QuantaCommon::attrCase(element)+">"));
+ } else
+ {
+ w->insertTag(tag,QuantaCommon::tagCase(""));
+ }
+ }
+ }
+ delete miscDlg;
+}
+
+
+/** do quick list */
+void QuantaApp::slotTagQuickList()
+{
+ QString space =" " ;
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+
+ TagQuickListDlg *listDlg = new TagQuickListDlg(this,i18n("Generate List"));
+ if ( listDlg->exec() ) {
+ int i;
+ int n = listDlg->spinBoxRows->value();
+
+ QString tag;
+ if ( listDlg->radioOrdered->isChecked())
+ tag = QString("<ol>\n")+space;
+ else tag = QString("<ul>\n")+space;
+
+ for ( i=0;i<n;i++)
+ if ( qConfig.closeTags )
+ tag += QString(" <li> </li>\n")+space;
+ else
+ tag += QString(" <li> \n")+space;
+
+ if ( listDlg->radioOrdered->isChecked())
+ tag += QString("</ol>");
+ else tag += QString("</ul>");
+
+ w->insertTag( QuantaCommon::tagCase(tag));
+ }
+ delete(listDlg);
+}
+
+void QuantaApp::slotTagEditTable()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+ baseNode = parser->rebuild(w);
+ QStringList list = w->tagAreas("table", true, false);
+ bool tableExists = false;
+ uint line, col;
+ w->viewCursorIf->cursorPositionReal(&line, &col);
+ int bl, bc, el, ec;
+ int bLine, bCol, eLine, eCol;
+ bLine = bCol = eLine = eCol = 0;
+ QStringList l;
+ QStringList l2;
+ for (QStringList::Iterator it = list.begin(); it != list.end(); ++it)
+ {
+ QuantaCommon::normalizeStructure(*it, l2);
+ l = QStringList::split('\n', *it, true);
+ QStringList coordList = QStringList::split(',', l[0], true);
+ bl = coordList[0].toInt();
+ bc = coordList[1].toInt();
+ el = coordList[2].toInt();
+ ec = coordList[3].toInt();
+ if (QuantaCommon::isBetween(line, col, bl, bc, el, ec) == 0)
+ {
+ tableExists = true;
+ bLine = bl;
+ bCol = bc;
+ eLine = el;
+ eCol = ec;
+ }
+ l.remove(l.begin());
+ }
+
+ TableEditor editor;
+ bool tableRead = true;
+ if (tableExists)
+ {
+ editor.setBaseURL(ViewManager::ref()->activeView()->baseURL());
+ tableRead = editor.setTableArea(bLine, bCol, eLine, eCol, parser);
+ if (!tableRead)
+ {
+ KMessageBox::error(this, i18n("The table structure is invalid. Most probably you forgot to close some tags."), i18n("Cannot Read Table"));
+ }
+ } else
+ {
+ Node *node = parser->nodeAt(line, col);
+ const DTDStruct *dtd = w->defaultDTD();
+ if (node)
+ dtd = node->tag->dtd();
+ bLine = line;
+ bCol = col;
+ eLine = line;
+ eCol = col;
+ editor.createNewTable(w, dtd);
+ }
+ if (tableRead && editor.exec())
+ {
+ QString tableString = editor.readModifiedTable();
+ w->activateParser(false);
+//#ifdef BUILD_KAFKAPART
+// if(w->editIfExt)
+// w->editIfExt->editBegin();
+//#endif
+ if (eLine != bLine || (eLine == bLine && eCol != bCol))
+ w->editIf->removeText(bLine, bCol, eLine, eCol + 1);
+ w->viewCursorIf->setCursorPositionReal((uint)bLine, (uint)bCol);
+ w->insertText(tableString, false);
+//#ifdef BUILD_KAFKAPART
+// if(w->editIfExt)
+// w->editIfExt->editEnd();
+//#endif
+ w->viewCursorIf->setCursorPositionReal(line, col);
+ reparse(true);
+ }
+}
+
+/** Open color Dialog and insert color in the text */
+void QuantaApp::slotTagColor()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+ QColor color;
+
+ if (KColorDialog::getColor( color )) {
+ char c[8];
+ sprintf(c,"#%2X%2X%2X",color.red(),color.green(),color.blue());
+ for (int i=0;i<7;i++) if (c[i] == ' ') c[i] = '0';
+ QString scolor = (char *)c;
+ w->insertTag(scolor);
+ }
+}
+
+/** insert date */
+void QuantaApp::slotTagDate()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+ time_t tektime;
+ time( &tektime);
+ QString stime = ctime( &tektime);
+
+ w->insertTag( stime);
+}
+
+/** for select form */
+void QuantaApp::slotTagSelect()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+ w->insertTag(QuantaCommon::tagCase("<select")+ QuantaCommon::attrCase("name")+QuantaCommon::tagCase("=\"\"><option>"),QuantaCommon::tagCase("</select>"));
+}
+
+void QuantaApp::slotViewInKFM()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+ if (w->isModified())
+ {
+ if ( KMessageBox::questionYesNo(this,
+ i18n("The file must be saved before external preview.\n"
+ "Do you want to save and preview?"),
+ i18n("Save Before Preview"),
+ KStdGuiItem::save(),KStdGuiItem::dontSave(), "AskForSaveBeforePreview")
+ == KMessageBox::Yes)
+ {
+ if (w->isUntitled())
+ {
+ quantaApp->slotFileSaveAs();
+ }
+ else
+ {
+ w->save();
+ }
+ } else
+ {
+ return;
+ }
+ }
+ if ( !w->isUntitled() )
+ {
+ KProcess *show = new KProcess(this);
+ KURL url = Project::ref()->urlWithPrefix(w->url());
+ *show << "kfmclient" << "newTab" << url.url();
+ show->start( KProcess::DontCare );
+ }
+}
+
+void QuantaApp::slotViewInLynx()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+ if (w->isModified())
+ {
+ if ( KMessageBox::questionYesNo(this,
+ i18n("The file must be saved before external preview.\n"
+ "Do you want to save and preview?"),
+ i18n("Save Before Preview"),KStdGuiItem::save(),KStdGuiItem::dontSave(), "AskForSaveBeforePreview")
+ == KMessageBox::Yes)
+ {
+ if (w->isUntitled())
+ {
+ quantaApp->slotFileSaveAs();
+ }
+ else
+ {
+ w->save();
+ }
+ } else
+ {
+ return;
+ }
+ }
+ if ( !w->isUntitled() )
+ {
+ KProcess *show = new KProcess(this);
+ KURL url = Project::ref()->urlWithPrefix(w->url());
+ *show << "konsole"
+ << "--nohist"
+ << "--notoolbar"
+ << "--caption"
+ << "Lynx Preview - Quanta"
+ << "-e"
+ << "lynx"
+ << url.url();
+ show->start( KProcess::DontCare );
+ }
+}
+
+/** insert clipboard contents (but quote them for HTML first) */
+void QuantaApp::slotPasteHTMLQuoted()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ QClipboard *cb = qApp->clipboard();
+ QString text = cb->text();
+
+ if ( ( !text.isNull() ) && (!text.isEmpty() ) )
+ {
+ text.replace( "&", "&amp;" );
+ text.replace( "<", "&lt;" );
+ text.replace( "\"", "&quot;" );
+ text.replace( ">", "&gt;" );
+
+//TODO: Replace only the chars not present in the current encoding.
+ QString encoding = defaultEncoding();
+ KTextEditor::EncodingInterface* encodingIf = dynamic_cast<KTextEditor::EncodingInterface*>(w->doc());
+ if (encodingIf)
+ encoding = encodingIf->encoding();
+ if (encoding != "UTF-8" && encoding != "UTF-16" && encoding != "ISO-10646-UCS-2")
+ {
+ for ( QStringList::Iterator it = charList.begin(); it != charList.end(); ++it )
+ {
+ QString s = *it;
+ int begin = s.find("(&#") + 3;
+ if (begin == 1)
+ continue;
+ int length = s.find(";)") - begin + 1;
+ s = s.mid(begin, length - 1);
+ bool ok;
+ int code = s.toInt(&ok);
+ if (!ok || code < 191)
+ continue;
+ text.replace(QChar(code), QString("&#%1;").arg(s));
+ }
+ }
+ unsigned int line, col;
+ w->viewCursorIf->cursorPositionReal(&line, &col);
+ w->editIf->insertText(line, col, text );
+ }
+ }
+}
+
+/** insert clipboard contents (but quote them as a URL first) */
+void QuantaApp::slotPasteURLEncoded()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ QClipboard *cb = qApp->clipboard();
+ QString text = cb->text();
+
+ if ( ( !text.isNull() ) && (!text.isEmpty() ) )
+ {
+ text = KURL::encode_string( text );
+ unsigned int line, col;
+ w->viewCursorIf->cursorPositionReal(&line, &col);
+ w->editIf->insertText(line, col, text );
+ }
+ }
+}
+
+
+/** Kate related slots. */
+
+void QuantaApp::slotUndo ()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if(ViewManager::ref()->activeView()->hadLastFocus() == QuantaView::VPLFocus && w)
+ {
+ /**MessageBox::information(this, i18n("VPL does not support this functionality yet."),
+ QString::null, "show undo unavailable");*/
+ w->docUndoRedo->undo();
+ return;
+ }
+ if (w)
+ {
+ bool updateClosing = qConfig.updateClosingTags;
+ qConfig.updateClosingTags = false;
+//#ifdef BUILD_KAFKAPART
+// write()->docUndoRedo.undo(false);
+//#else
+ KTextEditor::UndoInterface* undoIf = dynamic_cast<KTextEditor::UndoInterface*>(w->doc());
+ if (undoIf)
+ undoIf->undo();
+//#endif
+ qConfig.updateClosingTags = updateClosing;
+ }
+}
+
+void QuantaApp::slotRedo ()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if(ViewManager::ref()->activeView()->hadLastFocus() == QuantaView::VPLFocus)
+ {
+ /**KMessageBox::information(this, i18n("VPL does not support this functionality yet."),
+ QString::null, "show redo unavailable");*/
+ w->docUndoRedo->redo();
+ return;
+ }
+ if (w)
+ {
+ bool updateClosing = qConfig.updateClosingTags;
+ qConfig.updateClosingTags = false;
+//#ifdef BUILD_KAFKAPART
+// write()->docUndoRedo.redo(false);
+//#else
+ KTextEditor::UndoInterface* undoIf = dynamic_cast<KTextEditor::UndoInterface*>(w->doc());
+ if (undoIf)
+ undoIf->redo();
+//#endif
+ qConfig.updateClosingTags = updateClosing;
+ }
+}
+
+/** insert special character */
+void QuantaApp::slotInsertChar()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (w)
+ {
+ SpecialCharDialog S( this, "special_char" );
+ if (S.exec())
+ w->insertTag(S.selection());
+ }
+}
+
+void QuantaApp::slotCut()
+{
+ QuantaView* view = ViewManager::ref()->activeView();
+ Document *w = ViewManager::ref()->activeDocument();
+ if(view && view->hadLastFocus() == QuantaView::VPLFocus)
+ {
+ /*
+ KMessageBox::information(this, i18n("Sorry, VPL does not support this functionality yet."),
+ QString::null, "show cut unavailable");
+ */
+ KafkaDocument::ref()->slotCut();
+ return;
+ }
+ if(w)
+ {
+ KTextEditor::ClipboardInterface* clip = dynamic_cast<KTextEditor::ClipboardInterface*>(w->view());
+ if(clip)
+ clip->cut();
+ }
+}
+
+void QuantaApp::slotCopy()
+{
+ QuantaView* view = ViewManager::ref()->activeView();
+ Document *w = ViewManager::ref()->activeDocument();
+ if(view && view->hadLastFocus() == QuantaView::VPLFocus)
+ {
+ //KMessageBox::information(this, i18n("Sorry, VPL does not support this functionality yet."),
+ //QString::null, "show copy unavailable");
+ KafkaDocument::ref()->slotCopy();
+ return;
+ }
+ if (w)
+ {
+ KTextEditor::ClipboardInterface* clip = dynamic_cast<KTextEditor::ClipboardInterface*>(w->view());
+ if (clip)
+ clip->copy();
+ }
+ if (m_htmlPart->view()->hasFocus())
+ {
+ QString selection = m_htmlPart->selectedText();
+ QClipboard *cb = QApplication::clipboard();
+ cb->setText(selection, QClipboard::Clipboard);
+ }
+ else
+ if (m_htmlPartDoc->view()->hasFocus())
+ {
+ QString selection = m_htmlPartDoc->selectedText();
+ QClipboard *cb = QApplication::clipboard();
+ cb->setText(selection, QClipboard::Clipboard);
+ }
+
+}
+
+void QuantaApp::slotPaste()
+{
+ QuantaView* view = ViewManager::ref()->activeView();
+ Document *w = ViewManager::ref()->activeDocument();
+ if(view && view->hadLastFocus() == QuantaView::VPLFocus)
+ {
+ //KMessageBox::information(this, i18n("Sorry, VPL does not support this functionality yet."),
+ //QString::null, "show paste unavailable");
+ KafkaDocument::ref()->slotPaste();
+ return;
+ }
+ if(w)
+ {
+ KTextEditor::ClipboardInterface* clip = dynamic_cast<KTextEditor::ClipboardInterface*>(w->view());
+ if(clip)
+ clip->paste();
+ }
+}
+
+Node *QuantaApp::showTagDialogAndReturnNode(const QString &tag, const QString &attr)
+{
+ Node *n = 0L;
+ QuantaView *view = ViewManager::ref()->activeView();
+ if(view && view->document())
+ {
+ Document *w = view->document();
+
+ QString selection;
+ if(view->hadLastFocus() == QuantaView::VPLFocus)
+ selection = KafkaDocument::ref()->getKafkaWidget()->selectedText();
+
+ TagDialog *dlg = new TagDialog(QuantaCommon::tagFromDTD(w->getDTDIdentifier(),tag), selection, attr, ViewManager::ref()->activeView()->baseURL());
+ if (dlg->exec())
+ {
+ n= dlg->buildNode(w);
+ }
+
+ delete dlg;
+ }
+ return n;
+}
+
+
+void QuantaApp::slotShowSourceEditor()
+{
+ if (!showVPLAction->isChecked() && !showSourceAction->isChecked() && !showVPLSourceAction->isChecked())
+ showSourceAction->activate();
+ else
+ ViewManager::ref()->activeView()->slotSetSourceLayout();
+}
+
+void QuantaApp::slotShowVPLAndSourceEditor()
+{
+ if (!showVPLAction->isChecked() && !showSourceAction->isChecked() && !showVPLSourceAction->isChecked())
+ showSourceAction->activate();
+ else
+ ViewManager::ref()->activeView()->slotSetSourceAndVPLLayout();
+}
+
+void QuantaApp::slotShowVPLOnly()
+{
+ if (!showVPLAction->isChecked() && !showSourceAction->isChecked() && !showVPLSourceAction->isChecked())
+ showSourceAction->activate();
+ else
+ ViewManager::ref()->activeView()->slotSetVPLOnlyLayout();
+}
+
+void QuantaApp::initTabWidget(bool closeButtonsOnly)
+{
+ KTabWidget *tab = tabWidget();
+ KAcceleratorManager::setNoAccel(tab);
+ if (tab)
+ {
+ if (qConfig.showCloseButtons == "ShowAlways")
+ {
+ tab->setHoverCloseButton(true);
+ tab->setHoverCloseButtonDelayed(false);
+ } else
+ if (qConfig.showCloseButtons == "ShowDelayed")
+ {
+ tab->setHoverCloseButton(true);
+ tab->setHoverCloseButtonDelayed(true);
+ } else
+ {
+ tab->setHoverCloseButton(false);
+ }
+ if (!closeButtonsOnly)
+ {
+ tab->setTabReorderingEnabled(true);
+ tab->setTabPosition(QTabWidget::Bottom);
+ connect(tab, SIGNAL( contextMenu( QWidget *, const QPoint & ) ), ViewManager::ref(), SLOT(slotTabContextMenu( QWidget *, const QPoint & ) ) );
+ connect(tab, SIGNAL(initiateTabMove(int, int)), this, SLOT(slotTabAboutToMove(int, int))); connect(tab, SIGNAL(movedTab(int, int)), this, SLOT(slotTabMoved(int, int))); setTabWidgetVisibility(KMdi::AlwaysShowTabs);
+ }
+ }
+ if (!closeButtonsOnly)
+ setToolviewStyle(qConfig.toolviewTabs);
+}
+
+void QuantaApp::slotFileClosed(Document *w)
+{
+ if (w)
+ {
+ KURL url = w->url();
+ if (Project::ref()->hasProject() && Project::ref()->contains(url))
+ {
+ KURL u = QExtFileInfo::toRelative(url, Project::ref()->projectBaseURL());
+ m_annotationOutput->writeAnnotations(QuantaCommon::qUrl(u), w->annotations());
+ }
+ }
+}
+
+void QuantaApp::slotCVSCommandExecuted(const QString& command, const QStringList& files)
+{
+ QString file;
+ for (uint i = 0; i < files.count(); i++)
+ {
+ file = files[i];
+ if (Project::ref()->contains(KURL::fromPathOrURL(file)))
+ {
+ emit eventHappened("after_" + command, file, QString::null);
+ }
+ }
+}
+
+//overridden KMdiMainFrm slots
+void QuantaApp::closeActiveView()
+{
+ ViewManager::ref()->removeActiveView();
+}
+
+void QuantaApp::closeAllViews()
+{
+ ViewManager::ref()->closeAll();
+}
+
+void QuantaApp::resetDockLayout()
+{
+ QStringList groupList = m_config->groupList();
+ for (QStringList::Iterator it = groupList.begin(); it != groupList.end(); ++it)
+ {
+ if ((*it).startsWith("dock_setting_default"))
+ {
+ m_config->deleteGroup(*it);
+ }
+ }
+ m_config->sync();
+ QWidget *mainDockWidget = getMainDockWidget();
+ addToolWindow(fTab, KDockWidget::DockLeft, mainDockWidget);
+ addToolWindow(ProjectTreeView::ref(), KDockWidget::DockLeft, mainDockWidget);
+ addToolWindow(TemplatesTreeView::ref(), KDockWidget::DockLeft, mainDockWidget);
+ addToolWindow(StructTreeView::ref(), KDockWidget::DockLeft, mainDockWidget);
+ addToolWindow(scriptTab, KDockWidget::DockLeft, mainDockWidget);
+ addToolWindow(dTab, KDockWidget::DockRight, mainDockWidget);
+ addToolWindow(aTab, KDockWidget::DockRight, mainDockWidget);
+ addToolWindow(m_messageOutput, KDockWidget::DockBottom, mainDockWidget);
+ addToolWindow(m_problemOutput, KDockWidget::DockBottom, mainDockWidget);
+ addToolWindow(m_annotationOutput, KDockWidget::DockBottom, mainDockWidget);
+ if (m_previewToolView)
+ m_previewToolView = addToolWindow(m_htmlPart->view(), KDockWidget::DockBottom, mainDockWidget);
+ if (m_documentationToolView)
+ m_documentationToolView= addToolWindow(m_htmlPartDoc->view(), KDockWidget::DockBottom, mainDockWidget);
+ for (QMap<QWidget*,KMdiToolViewAccessor*>::Iterator it = m_pToolViews->begin(); it != m_pToolViews->end(); ++it)
+ {
+ QWidget *widget = it.key();
+ if (dynamic_cast<ServerTreeView*>(widget))
+ addToolWindow(widget, KDockWidget::DockRight, mainDockWidget);
+ if (dynamic_cast<VariablesListView*>(widget))
+ addToolWindow(widget, KDockWidget::DockLeft, mainDockWidget);
+ if (dynamic_cast<DebuggerBreakpointView*>(widget))
+ addToolWindow(widget, KDockWidget::DockBottom, mainDockWidget);
+ }
+}
+
+KDockWidget::DockPosition QuantaApp::prevDockPosition(QWidget* widget, KDockWidget::DockPosition def)
+{
+ QMap<KDockWidget::DockPosition,QString> maps;
+ QMap<QString,QString> map;
+ QString dock = widget->name();
+
+ // Which groups to search through
+ maps[KDockWidget::DockTop] = "dock_setting_default::KMdiDock::topDock";
+ maps[KDockWidget::DockLeft] = "dock_setting_default::KMdiDock::leftDock";
+ maps[KDockWidget::DockBottom] = "dock_setting_default::KMdiDock::bottomDock";
+ maps[KDockWidget::DockRight] = "dock_setting_default::KMdiDock::rightDock";
+
+ // Loop the groups
+ for(QMap<KDockWidget::DockPosition,QString>::Iterator itmaps = maps.begin(); itmaps != maps.end(); ++itmaps )
+ {
+ // Loop the items in the group
+ map = quantaApp->config()->entryMap(itmaps.data());
+ for(QMap<QString,QString>::Iterator it = map.begin(); it != map.end(); ++it )
+ {
+ // If we found it, return the key of the group
+ if(it.data() == dock)
+ return itmaps.key();
+ }
+ }
+ return def;
+}
+
+void QuantaApp::switchToToplevelMode()
+{
+ KMdiMainFrm::switchToToplevelMode();
+ resetDockLayout();
+ initTabWidget();
+}
+
+void QuantaApp::switchToChildframeMode()
+{
+ KMdiMainFrm::switchToChildframeMode();
+ resetDockLayout();
+ initTabWidget();
+}
+
+void QuantaApp::switchToIDEAlMode()
+{
+ KMdiMainFrm::switchToIDEAlMode();
+ resetDockLayout();
+ initTabWidget();
+}
+
+void QuantaApp::switchToTabPageMode()
+{
+ KMdiMainFrm::switchToTabPageMode();
+ resetDockLayout();
+ initTabWidget();
+}
+
+void QuantaApp::slotPreviewBeingClosed()
+{
+ m_previewVisible = false;
+ m_noFramesPreview = false;
+ m_previewToolView = 0L; //this automatically deleted, so set to 0L
+ }
+
+void QuantaApp::slotDockWidgetHasUndocked(KDockWidget *widget)
+{
+ if (m_previewToolView && m_previewToolView->wrapperWidget() == widget)
+ slotPreviewBeingClosed();
+}
+
+void QuantaApp::slotTabDragged(QWidget *widget)
+{
+ QuantaView *view = dynamic_cast<QuantaView*>(widget);
+ if (view && view->document())
+ {
+ QString url = view->document()->url().url();
+ QDragObject *d = new QTextDrag( url, this );
+ d->dragCopy();
+ }
+}
+
+void QuantaApp::setTabToolTip(QWidget *w, const QString &toolTipStr)
+{
+ if (tabWidget())
+ tabWidget()->setTabToolTip(w, toolTipStr);
+}
+
+void QuantaApp::createPreviewPart()
+{
+ m_htmlPart = new WHTMLPart(this, "rightHTML", true);
+ m_htmlPart->view()->resize(0, 0);
+ m_htmlPart->view()->setIcon(UserIcon("preview"));
+ m_htmlPart->view()->setCaption(i18n("Preview"));
+ slotNewPart(m_htmlPart, false);
+ connect(m_htmlPart, SIGNAL(previewHasFocus(bool)), this, SLOT(slotPreviewHasFocus(bool)));
+ connect(m_htmlPart, SIGNAL(destroyed(QObject *)), this, SLOT(slotHTMLPartDeleted(QObject *)));
+ connect(m_htmlPart, SIGNAL(openFile(const KURL&, const QString&, bool)), this, SLOT(slotFileOpen(const KURL&, const QString&, bool)));
+ connect(m_htmlPart, SIGNAL(showPreview(bool)), this, SLOT(slotShowPreviewWidget(bool)));
+
+}
+
+void QuantaApp::createDocPart()
+{
+ m_htmlPartDoc = new WHTMLPart(this, "docHTML");
+ m_htmlPartDoc->view()->resize(0, 0);
+ m_htmlPartDoc->view()->setIcon(SmallIcon("contents"));
+ m_htmlPartDoc->view()->setCaption(i18n("Documentation"));
+ slotNewPart(m_htmlPartDoc, false);
+ connect(m_htmlPartDoc, SIGNAL(destroyed(QObject *)), this, SLOT(slotHTMLPartDeleted(QObject *)));
+}
+
+void QuantaApp::insertTagActionPoolItem(QString const& action_item)
+{
+ for(QStringList::Iterator it = m_tagActionPool.begin(); it != m_tagActionPool.end(); ++it)
+ if(action_item == *it)
+ return;
+
+ m_tagActionPool += action_item;
+}
+
+void QuantaApp::removeTagActionPoolItem(QString const& action_item)
+{
+ for(QStringList::Iterator it = m_tagActionPool.begin(); it != m_tagActionPool.end(); ++it)
+ {
+ if(action_item == *it)
+ {
+ m_tagActionPool.remove(it);
+ return;
+ }
+ }
+}
+
+void QuantaApp::slotHTMLPartDeleted(QObject *object)
+{
+ if (object == m_htmlPart)
+ {
+ createPreviewPart();
+ slotShowPreviewWidget(false);
+ } else
+ createDocPart();
+}
+
+void QuantaApp::slotTabMoved(int from, int to)
+{
+ KMdiChildView *view = m_pDocumentViews->at(from);
+ m_pDocumentViews->remove(from);
+ m_pDocumentViews->insert(to, view);
+ connect(this, SIGNAL(viewActivated (KMdiChildView *)), ViewManager::ref(), SLOT(slotViewActivated(KMdiChildView*)));
+}
+
+void QuantaApp::slotTabAboutToMove(int from, int to)
+{
+ Q_UNUSED(from);
+ Q_UNUSED(to);
+ disconnect(this, SIGNAL(viewActivated (KMdiChildView *)), ViewManager::ref(), SLOT(slotViewActivated(KMdiChildView*)));
+}
+
+QString QuantaApp::currentURL() const
+{
+ return ViewManager::ref()->currentURL();
+}
+
+void QuantaApp::slotAnnotate()
+{
+ Document *w = ViewManager::ref()->activeDocument();
+ if (!w) return;
+ uint line, column;
+ w->viewCursorIf->cursorPositionReal(&line, &column);
+ KDialogBase editDlg(this, "annotate", true, i18n("Annotate Document"), KDialogBase::Ok | KDialogBase::Cancel /*| KDialogBase::User1*/);
+ KTextEdit editor(&editDlg);
+ editor.setTextFormat(PlainText);
+ editor.setText(w->annotationText(line));
+ editDlg.setMainWidget(&editor);
+ //editDlg.setButtonText(KDialogBase::User1, i18n("Clear"));
+ if (editDlg.exec())
+ {
+ w->setAnnotationText(line, editor.text());
+ }
+}
+
+void QuantaApp::dropEvent(QDropEvent* event)
+{
+ if (KURLDrag::canDecode(event))
+ {
+ KURL::List fileList;
+ KURLDrag::decode(event, fileList);
+
+ if(fileList.empty())
+ return;
+
+ slotFileOpen(fileList, defaultEncoding());
+ }
+}
+
+void QuantaApp::dragEnterEvent( QDragEnterEvent *e)
+{
+ e->accept();
+}
+
+#include "quanta.moc"