?? revgraphview.cpp
字號:
//*stream << QString(" overlap=false;\n splines=true;\n"); RevGraphView::trevTree::ConstIterator it1; for (it1=m_Tree.begin();it1!=m_Tree.end();++it1) { *stream << " " << it1.key() << "[ " << "shape=box, " << "label=\""<<getLabelstring(it1.key())<<"\"," << "];\n"; for (unsigned j=0;j<it1.data().targets.count();++j) { *stream<<" "<<it1.key().latin1()<< " " << "->"<<" "<<it1.data().targets[j].key << " [fontsize=10,style=\"solid\"];\n"; } } *stream << "}\n"<<flush; renderProcess = new KProcess(); renderProcess->setEnvironment("LANG","C"); *renderProcess << "dot"; *renderProcess << dotTmpFile->name() << "-Tplain"; connect(renderProcess,SIGNAL(processExited(KProcess*)),this,SLOT(dotExit(KProcess*))); connect(renderProcess,SIGNAL(receivedStdout(KProcess*,char*,int)), this,SLOT(readDotOutput(KProcess*,char*,int)) ); if (!renderProcess->start(KProcess::NotifyOnExit,KProcess::Stdout)) { QString arguments; for (unsigned c=0;c<renderProcess->args().count();++c) { arguments+=QString(" %1").arg(renderProcess->args()[c]); } QString error = i18n("Could not start process \"%1\".").arg(arguments); showText(error); renderProcess=0; //delete renderProcess;< }}QString RevGraphView::toolTip(const QString&_nodename,bool full)const{ QString res = QString::null; trevTree::ConstIterator it; it = m_Tree.find(_nodename); if (it==m_Tree.end()) { return res; } QStringList sp = QStringList::split("\n",it.data().Message); QString sm; if (sp.count()==0) { sm = it.data().Message; } else { if (!full) { sm = sp[0]+"..."; } else { for (unsigned j = 0; j<sp.count(); ++j) { if (j>0) sm+="<br>"; sm+=sp[j]; } } } if (!full && sm.length()>50) { sm.truncate(47); sm+="..."; } static QString csep = "</td><td>"; static QString rend = "</td></tr>"; static QString rstart = "<tr><td>"; res = QString("<html><body>"); if (!full) { res+=QString("<b>%1</b>").arg(it.data().name); res += i18n("<br>Revision: %1<br>Author: %2<br>Date: %3<br>Log: %4</html>") .arg(it.data().rev) .arg(it.data().Author) .arg(it.data().Date) .arg(sm); } else { res+="<table><tr><th colspan=\"2\"><b>"+it.data().name+"</b></th></tr>"; res+=rstart; res+=i18n("<b>Revision</b>%1%2%3").arg(csep).arg(it.data().rev).arg(rend); res+=rstart+i18n("<b>Author</b>%1%2%3").arg(csep).arg(it.data().Author).arg(rend); res+=rstart+i18n("<b>Date</b>%1%2%3").arg(csep).arg(it.data().Date).arg(rend); res+=rstart+i18n("<b>Log</b>%1%2%3").arg(csep).arg(sm).arg(rend); res+="</table></body></html>"; } return res;}void RevGraphView::updateSizes(QSize s){ if (!m_Canvas) return; if (s == QSize(0,0)) s = size(); // the part of the canvas that should be visible int cWidth = m_Canvas->width() - 2*_xMargin + 100; int cHeight = m_Canvas->height() - 2*_yMargin + 100; // hide birds eye view if no overview needed if (((cWidth < s.width()) && cHeight < s.height())||m_NodeList.count()==0) { m_CompleteView->hide(); return; } m_CompleteView->show(); // first, assume use of 1/3 of width/height (possible larger) double zoom = .33 * s.width() / cWidth; if (zoom * cHeight < .33 * s.height()) zoom = .33 * s.height() / cHeight; // fit to widget size if (cWidth * zoom > s.width()) zoom = s.width() / (double)cWidth; if (cHeight * zoom > s.height()) zoom = s.height() / (double)cHeight; // scale to never use full height/width zoom = zoom * 3/4; // at most a zoom of 1/3 if (zoom > .33) zoom = .33; if (zoom != _cvZoom) { _cvZoom = zoom; if (0) qDebug("Canvas Size: %dx%d, Visible: %dx%d, Zoom: %f", m_Canvas->width(), m_Canvas->height(), cWidth, cHeight, zoom); QWMatrix wm; wm.scale( zoom, zoom ); m_CompleteView->setWorldMatrix(wm); // make it a little bigger to compensate for widget frame m_CompleteView->resize(int(cWidth * zoom) + 4, int(cHeight * zoom) + 4); // update ZoomRect in completeView contentsMovingSlot(contentsX(), contentsY()); } m_CompleteView->setContentsPos(int(zoom*(_xMargin-50)), int(zoom*(_yMargin-50))); updateZoomerPos();}void RevGraphView::updateZoomerPos(){ int cvW = m_CompleteView->width(); int cvH = m_CompleteView->height(); int x = width()- cvW - verticalScrollBar()->width() -2; int y = height()-cvH - horizontalScrollBar()->height() -2; QPoint oldZoomPos = m_CompleteView->pos(); QPoint newZoomPos = QPoint(0,0);#if 0 ZoomPosition zp = _zoomPosition; if (zp == Auto) {#else ZoomPosition zp = m_LastAutoPosition;#endif QPoint tl1Pos = viewportToContents(QPoint(0,0)); QPoint tl2Pos = viewportToContents(QPoint(cvW,cvH)); QPoint tr1Pos = viewportToContents(QPoint(x,0)); QPoint tr2Pos = viewportToContents(QPoint(x+cvW,cvH)); QPoint bl1Pos = viewportToContents(QPoint(0,y)); QPoint bl2Pos = viewportToContents(QPoint(cvW,y+cvH)); QPoint br1Pos = viewportToContents(QPoint(x,y)); QPoint br2Pos = viewportToContents(QPoint(x+cvW,y+cvH)); int tlCols = m_Canvas->collisions(QRect(tl1Pos,tl2Pos)).count(); int trCols = m_Canvas->collisions(QRect(tr1Pos,tr2Pos)).count(); int blCols = m_Canvas->collisions(QRect(bl1Pos,bl2Pos)).count(); int brCols = m_Canvas->collisions(QRect(br1Pos,br2Pos)).count(); int minCols = tlCols; zp = m_LastAutoPosition; switch(zp) { case TopRight: minCols = trCols; break; case BottomLeft: minCols = blCols; break; case BottomRight: minCols = brCols; break; default: case TopLeft: minCols = tlCols; break; } if (minCols > tlCols) { minCols = tlCols; zp = TopLeft; } if (minCols > trCols) { minCols = trCols; zp = TopRight; } if (minCols > blCols) { minCols = blCols; zp = BottomLeft; } if (minCols > brCols) { minCols = brCols; zp = BottomRight; } m_LastAutoPosition = zp;#if 0 }#endif switch(zp) { case TopRight: newZoomPos = QPoint(x,0); break; case BottomLeft: newZoomPos = QPoint(0,y); break; case BottomRight: newZoomPos = QPoint(x,y); break; default: break; } if (newZoomPos != oldZoomPos) m_CompleteView->move(newZoomPos);}void RevGraphView::contentsMovingSlot(int x,int y){ QRect z(int(x * _cvZoom), int(y * _cvZoom), int(visibleWidth() * _cvZoom)-1, int(visibleHeight() * _cvZoom)-1); if (0) qDebug("moving: (%d,%d) => (%d/%d - %dx%d)", x, y, z.x(), z.y(), z.width(), z.height()); m_CompleteView->setZoomRect(z); if (!_noUpdateZoomerPos) { updateZoomerPos(); }}void RevGraphView::zoomRectMoved(int dx,int dy){ if (leftMargin()>0) dx = 0; if (topMargin()>0) dy = 0; _noUpdateZoomerPos = true; scrollBy(int(dx/_cvZoom),int(dy/_cvZoom)); _noUpdateZoomerPos = false;}void RevGraphView::zoomRectMoveFinished(){#if 0 if (_zoomPosition == Auto)#endif updateZoomerPos();}void RevGraphView::resizeEvent(QResizeEvent*e){ QCanvasView::resizeEvent(e); if (m_Canvas) updateSizes(e->size());}void RevGraphView::makeSelected(GraphTreeLabel*gtl){ if (m_Selected) { m_Selected->setSelected(false); } m_Selected=gtl; if (m_Marker) { m_Marker->hide(); delete m_Marker; m_Marker=0; } if (gtl) { m_Marker = new GraphMark(gtl,m_Canvas); m_Marker->setZ(-1); m_Marker->show(); m_Selected->setSelected(true); } m_Canvas->update(); m_CompleteView->updateCurrentRect();}void RevGraphView::contentsMouseDoubleClickEvent ( QMouseEvent * e ){ setFocus(); if (e->button() == Qt::LeftButton) { QCanvasItemList l = canvas()->collisions(e->pos()); if (l.count()>0) { QCanvasItem* i = l.first(); if (i->rtti()==GRAPHTREE_LABEL) { makeSelected( (GraphTreeLabel*)i); emit dispDetails(toolTip(((GraphTreeLabel*)i)->nodename(),true)); } } }}void RevGraphView::contentsMousePressEvent ( QMouseEvent * e ){ setFocus(); _isMoving = true; _lastPos = e->globalPos();}void RevGraphView::contentsMouseReleaseEvent ( QMouseEvent * ){ _isMoving = false; updateZoomerPos();}void RevGraphView::contentsMouseMoveEvent ( QMouseEvent * e ){ if (_isMoving) { int dx = e->globalPos().x() - _lastPos.x(); int dy = e->globalPos().y() - _lastPos.y(); _noUpdateZoomerPos = true; scrollBy(-dx, -dy); _noUpdateZoomerPos = false; _lastPos = e->globalPos(); }}void RevGraphView::setNewDirection(int dir){ if (dir<0)dir=3; else if (dir>3)dir=0; Kdesvnsettings::setTree_direction(dir); dumpRevtree();}void RevGraphView::contentsContextMenuEvent(QContextMenuEvent* e){ if (!m_Canvas) return; QCanvasItemList l = canvas()->collisions(e->pos()); QCanvasItem* i = (l.count() == 0) ? 0 : l.first(); QPopupMenu popup; if (i && i->rtti()==GRAPHTREE_LABEL) { if (!((GraphTreeLabel*)i)->source().isEmpty() && getAction(((GraphTreeLabel*)i)->nodename())!='D') { popup.insertItem(i18n("Diff to previous"),301); } if (m_Selected && m_Selected != i && getAction(m_Selected->nodename())!='D' && getAction(((GraphTreeLabel*)i)->nodename())!='D') { popup.insertItem(i18n("Diff to selected item"),302); } if (getAction(((GraphTreeLabel*)i)->nodename())!='D') { popup.insertItem(i18n("Cat this version"),303); } if (m_Selected == i) { popup.insertItem(i18n("Unselect item"),401); } else { popup.insertItem(i18n("Select item"),402); } popup.insertSeparator(); popup.insertItem(i18n("Display details"),403); popup.insertSeparator(); } popup.insertItem(i18n("Rotate counter-clockwise"),101); popup.insertItem(i18n("Rotate clockwise"),102); popup.insertSeparator(); int it = popup.insertItem(i18n("Diff in revisiontree is recursive"),202); popup.setCheckable(true); popup.setItemChecked(it,Kdesvnsettings::tree_diff_rec()); popup.insertItem(i18n("Save tree as png"),201); int r = popup.exec(e->globalPos()); switch (r) { case 101: { int dir = Kdesvnsettings::tree_direction(); setNewDirection(++dir); } break; case 102: { int dir = Kdesvnsettings::tree_direction(); setNewDirection(--dir); } break; case 201: { QString fn = KFileDialog::getSaveFileName(":","*.png"); if (!fn.isEmpty()) { if (m_Marker) { m_Marker->hide(); } if (m_Selected) { m_Selected->setSelected(false); } QPixmap pix(m_Canvas->size()); QPainter p(&pix); m_Canvas->drawArea( m_Canvas->rect(), &p ); pix.save(fn,"PNG"); if (m_Marker) { m_Marker->show(); } if (m_Selected) { m_Selected->setSelected(true); m_Canvas->update(); m_CompleteView->updateCurrentRect(); } } } case 202: { Kdesvnsettings::setTree_diff_rec(!Kdesvnsettings::tree_diff_rec()); break; } break; case 301: if (i && i->rtti()==GRAPHTREE_LABEL && !((GraphTreeLabel*)i)->source().isEmpty()) { makeDiffPrev((GraphTreeLabel*)i); } break; case 302: if (i && i->rtti()==GRAPHTREE_LABEL && m_Selected) { makeDiff(((GraphTreeLabel*)i)->nodename(),m_Selected->nodename()); } break; case 303: if (i && i->rtti()==GRAPHTREE_LABEL) { makeCat((GraphTreeLabel*)i); } break; case 401: makeSelected(0); break; case 402: makeSelected((GraphTreeLabel*)i); break; case 403: emit dispDetails(toolTip(((GraphTreeLabel*)i)->nodename(),true)); break; default: break; }}void RevGraphView::makeCat(GraphTreeLabel*_l){ if (!_l) { return; } QString n1 = _l->nodename(); trevTree::ConstIterator it = m_Tree.find(n1); if (it==m_Tree.end()) { return; } svn::Revision tr(it.data().rev); QString tp = _basePath+it.data().name; emit makeCat(tr,tp,it.data().name,tr,kapp->activeModalWidget());}void RevGraphView::makeDiffPrev(GraphTreeLabel*_l){ if (!_l) return; QString n1,n2; n1 = _l->nodename(); n2 = _l->source(); makeDiff(n1,n2);}void RevGraphView::makeDiff(const QString&n1,const QString&n2){ if (n1.isEmpty()||n2.isEmpty()) return; trevTree::ConstIterator it; it = m_Tree.find(n2); if (it==m_Tree.end()) { return; } svn::Revision sr(it.data().rev); QString sp = _basePath+it.data().name; it = m_Tree.find(n1); if (it==m_Tree.end()) { return; } svn::Revision tr(it.data().rev); QString tp = _basePath+it.data().name; if (Kdesvnsettings::tree_diff_rec()) { emit makeRecDiff(sp,sr,tp,tr,kapp->activeModalWidget()); } else { emit makeNorecDiff(sp,sr,tp,tr,kapp->activeModalWidget()); }}void RevGraphView::setBasePath(const QString&_path){ _basePath = _path;}void RevGraphView::slotClientException(const QString&what){ KMessageBox::sorry(KApplication::activeModalWidget(),what,i18n("SVN Error"));}#include "revgraphview.moc"
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -