/*************************************************************************** quantadoc.cpp - description ------------------- begin : ���� 9 13:29:57 EEST 2000 copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon (C) 2001-2003 Andras Mantia ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // include files for TQt #include #include #include #include #include #include #include #include // include files for KDE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // application specific includes #include "document.h" #include "quanta.h" #include "quantadoc.h" #include "quantaview.h" #include "viewmanager.h" #include "quantacommon.h" #include "qextfileinfo.h" #include "resource.h" #include "debuggermanager.h" #include "project.h" //#include "dtds.h" #include "undoredo.h" #include "tagactionmanager.h" #include "tagactionset.h" QuantaDoc::QuantaDoc(TQWidget *parent, const char *name) : TQObject(parent, name) { fileWatcher = new KDirWatch(this); attribMenu = new TDEPopupMenu(); attribMenu->insertTitle(i18n("Tag")); connect( attribMenu, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotInsertAttrib(int))); } QuantaDoc::~QuantaDoc() { //kdDebug(24000) << "QuantaDoc::~QuantaDoc: " << endl; } bool QuantaDoc::newDocument( const KURL& url, bool switchToExisting ) { bool newfile = false; if ( url.url().isEmpty() ) newfile = true; Document *w = 0L; QuantaView *view = ViewManager::ref()->isOpened(url); if (!view || newfile) { w = ViewManager::ref()->activeDocument(); if (w && !newfile && !w->isModified() && w->isUntitled() && !w->busy) ViewManager::ref()->removeActiveView(false); /* // no modi and new -> we can remove !!!! w = ViewManager::ref()->activeDocument(); if (w && !w->isModified() && w->isUntitled() && !w->busy) { //workaround for some strange Katepart behavior. If there is a highlighting mode //selected and new content is loaded, the highlighting is reset to None. To avoid this //remove the untitled document and create a new one, where we don't set the //highlighting ViewManager::ref()->removeActiveView(false); w = ViewManager::ref()->activeDocument(); if (w && !w->isModified() && w->isUntitled() && !w->busy) return true; } */ // now we can create new kwrite ViewManager::ref()->createNewDocument(); view = ViewManager::ref()->activeView(); if (Project::ref()->hasProject()) view->document()->processDTD(Project::ref()->defaultDTD()); else view->document()->processDTD(qConfig.defaultDocType); } else // select opened if (switchToExisting) { view->document()->checkDirtyStatus(); if (view != ViewManager::ref()->activeView()) { view->activate(); view->activated(); } return false; // don't need loadURL } return true; } void QuantaDoc::openDocument(const KURL& urlToOpen, const TQString &a_encoding, bool switchToExisting, bool readOnly) { bool idleTimerStatus = quantaApp->slotEnableIdleTimer(false); KURL url = urlToOpen; if (url.isLocalFile()) { TQString path = TQDir(url.path()).canonicalPath(); if (!path.isEmpty()) url.setPath(path); } TQString encoding = a_encoding; if (!newDocument(url, switchToExisting)) { quantaApp->slotEnableIdleTimer(idleTimerStatus); return; } Document *w = ViewManager::ref()->activeDocument(); if (readOnly) { //might work only with Kate part TDEAction *writeLockAction = w->view()->actionCollection()->action("tools_toggle_write_lock"); if (writeLockAction) writeLockAction->activate(); } if (!url.isEmpty()) { if (QExtFileInfo::exists(url, true, quantaApp)) { if (encoding.isEmpty()) encoding = quantaApp->defaultEncoding(); w->disconnect(TQ_SIGNAL(openingFailed(const KURL&))); connect(w, TQ_SIGNAL(openingFailed(const KURL&)), this, TQ_SLOT(slotOpeningFailed(const KURL&))); w->disconnect(TQ_SIGNAL(openingCompleted(const KURL&))); connect(w, TQ_SIGNAL(openingCompleted(const KURL&)), this, TQ_SLOT(slotOpeningCompleted(const KURL&))); w->open(url, encoding); quantaApp->setTitle(url.prettyURL(0, KURL::StripFileProtocol)); } else { slotOpeningFailed(url); } } else { quantaApp->reparse(true); KTextEditor::HighlightingInterface* highlightIf = dynamic_cast(w->doc()); if (highlightIf) { TQString hlName; int htmlIdx = -1, xmlIdx = -1; for (uint i = 0; i < highlightIf->hlModeCount(); i++) { hlName = highlightIf->hlModeName(i); if (hlName == "HTML") htmlIdx = i; if (hlName == "XML") xmlIdx = i; } const DTDStruct *dtd = w->defaultDTD(); if (dtd->family == 1) { if (dtd->singleTagStyle == "xml") highlightIf->setHlMode(xmlIdx); else highlightIf->setHlMode(htmlIdx); } } emit newStatus(); } quantaApp->slotEnableIdleTimer(idleTimerStatus); } void QuantaDoc::slotOpeningFailed(const KURL &url) { Q_UNUSED(url); bool signalStatus = signalsBlocked(); blockSignals(false); emit hideSplash(); //Seems to be not needed anymore since KDE 3.2, but keep until it's completely verified /* KMessageBox::error(quantaApp, i18n("Cannot open document %1.").arg(url.prettyURL(0, KURL::StripFileProtocol))); */ ViewManager::ref()->removeActiveView(); blockSignals(signalStatus); } void QuantaDoc::slotOpeningCompleted(const KURL &url) { Document *w = ViewManager::ref()->activeDocument(); Project::ref()->loadBookmarks(w->url(), dynamic_cast(w->doc())); quantaApp->fileRecent->addURL(url); quantaApp->slotRepaintPreview(); quantaApp->reparse(true); if (url.isLocalFile()) quantaApp->debugger()->fileOpened(url.prettyURL(0, KURL::StripFileProtocol)); quantaApp->slotNewStatus(); quantaApp->setTitle(url.prettyURL(0, KURL::StripFileProtocol)); Project::ref()->loadCursorPosition(w->url(), dynamic_cast(w->view())); emit eventHappened("after_open", url.url(), TQString()); bool flag = TagActionManager::canIndentDTD(w->defaultDTD()->name); quantaApp->actionCollection()->action("apply_source_indentation")->setEnabled(flag); } /** show popup menu with list of attributes for current tag */ void QuantaDoc::slotAttribPopup() { Document *w = ViewManager::ref()->activeDocument(); if (!w) return; attribMenu->clear(); uint line, col; w->viewCursorIf->cursorPositionReal(&line, &col); Node *node = parser->nodeAt(line, col, false); if (node && node->tag) { Tag *tag = node->tag; TQString tagName = tag->name; TQStrIList attrList = TQStrIList(); TQString name; for (int i=0; i < tag->attrCount(); i++ ) attrList.append( tag->attribute(i).ascii() ); if ( QuantaCommon::isKnownTag(w->getDTDIdentifier(),tagName) ) { TQString caption = i18n("Attributes of <%1>").arg(tagName); attribMenu->insertTitle( caption ); AttributeList *list = QuantaCommon::tagAttributes(w->getDTDIdentifier(),tagName ); uint menuId = 0; for ( uint i = 0; i < list->count(); i++ ) { name = list->at(i)->name; attribMenu->insertItem( name , i);//list->findIndex(*item) ); if (attrList.contains(name.ascii())) { attribMenu->setItemEnabled( i , false ); } menuId++; } TQTag* qtag = QuantaCommon::tagFromDTD(w->getDTDIdentifier(), tagName); for (TQStringList::Iterator it = qtag->commonGroups.begin(); it != qtag->commonGroups.end(); ++it) { TQPopupMenu* popUpMenu = new TQPopupMenu(attribMenu, (*it).latin1()); AttributeList *attrs = qtag->parentDTD->commonAttrs->find(*it); for (uint j = 0; j < attrs->count(); j++) { name = attrs->at(j)->name; popUpMenu->insertItem(name, ++menuId); if (attrList.contains(name.ascii())) { popUpMenu->setItemEnabled( menuId , false ); } } connect( popUpMenu, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotInsertAttrib(int))); attribMenu->insertItem(*it, popUpMenu); } if (menuId > 0) // don't show empty menu, may be core dumped { attribMenu->setActiveItem( 0); TQPoint globalPos = w->view()->mapToGlobal(w->viewCursorIf->cursorCoordinates()); TQFont font = w->view()->font(); globalPos.setY(globalPos.y() + TQFontMetrics(font).height()); attribMenu->exec(globalPos); } } else { TQString message = i18n("Unknown tag: %1").arg(tagName); quantaApp->slotStatusMsg( message ); } } } void QuantaDoc::slotInsertAttrib( int id ) { Document *w = ViewManager::ref()->activeDocument(); if (!w) return; uint line, col; w->viewCursorIf->cursorPositionReal(&line, &col); Node *node = parser->nodeAt(line, col); if (node && node->tag) { Tag *tag = node->tag; TQString tagName = tag->name; if ( QuantaCommon::isKnownTag(w->getDTDIdentifier(), tagName) ) { int menuId; AttributeList *list = QuantaCommon::tagAttributes(w->getDTDIdentifier(), tagName); menuId = list->count(); TQString attrStr; if (id <= menuId) { attrStr = list->at(id)->name; } else { TQTag* qtag = QuantaCommon::tagFromDTD(w->getDTDIdentifier(), tagName); for (TQStringList::Iterator it = qtag->commonGroups.begin(); it != qtag->commonGroups.end(); ++it) { AttributeList *attrs = qtag->parentDTD->commonAttrs->find(*it); menuId += attrs->count(); if (id <= menuId) { attrStr = attrs->at(id - (menuId - attrs->count()) -1)->name; break; } } } //now insert the new attribute into the tag int el, ec; tag->endPos(el, ec); w->viewCursorIf->setCursorPositionReal( el, ec ); w->insertTag( " " + QuantaCommon::attrCase(attrStr) + "="+qConfig.attrValueQuotation, qConfig.attrValueQuotation ); } delete attribMenu; attribMenu = new TDEPopupMenu(); attribMenu->insertTitle(i18n("Tag")); connect( attribMenu, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotInsertAttrib(int))); } } #include "quantadoc.moc"