diff --git a/sublime/mainwindow.cpp b/sublime/mainwindow.cpp index 578446737c..4cc4250698 100644 --- a/sublime/mainwindow.cpp +++ b/sublime/mainwindow.cpp @@ -1,456 +1,456 @@ /*************************************************************************** * Copyright 2006-2007 Alexander Dymo * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "mainwindow.h" #include "mainwindow_p.h" #include #include #include #include #include #include #include #include #include #include #include #include "area.h" #include "view.h" #include "controller.h" #include "container.h" #include "ideal.h" namespace Sublime { MainWindow::MainWindow(Controller *controller, Qt::WindowFlags flags) : KParts::MainWindow(0, flags), d(new MainWindowPrivate(this, controller)) { connect(this, SIGNAL(destroyed()), controller, SLOT(areaReleased())); loadGeometry(KGlobal::config()->group("Main Window")); d->areaSwitcher = new AreaTabWidget(menuBar()); menuBar()->setCornerWidget(d->areaSwitcher, Qt::TopRightCorner); // don't allow AllowTabbedDocks - that doesn't make sense for "ideal" UI setDockOptions(QMainWindow::AnimatedDocks); } QWidget* MainWindow::customButtonForAreaSwitcher ( Area* /*area*/ ) { return 0; } bool MainWindow::containsView(View* view) const { foreach(Area* area, areas()) if(area->views().contains(view)) return true; return false; } QList< Area* > MainWindow::areas() const { QList< Area* > areas = controller()->areas(const_cast(this)); if(areas.isEmpty()) areas = controller()->defaultAreas(); return areas; } void MainWindow::setupAreaSelector() { disconnect(d->areaSwitcher->tabBar, SIGNAL(currentChanged(int)), d, SLOT(toggleArea(int))); d->areaSwitcher->setUpdatesEnabled(false); d->areaSwitcher->tabBar->clearTabs(); int currentIndex = -1; QList< Area* > areas = this->areas(); QSet hadAreaName; for(int a = 0; a < areas.size(); ++a) { Area* theArea = areas[a]; if(hadAreaName.contains(theArea->objectName())) continue; hadAreaName.insert(theArea->objectName()); if(theArea->objectName() == area()->objectName()) { currentIndex = a; } d->areaSwitcher->tabBar->addCustomTab(theArea->title(), KIcon(theArea->iconName()), currentIndex == a, theArea->objectName(), customButtonForAreaSwitcher(theArea)); } d->areaSwitcher->tabBar->setCurrentIndex(currentIndex); d->areaSwitcher->updateGeometry(); d->areaSwitcher->setUpdatesEnabled(true); connect(d->areaSwitcher->tabBar, SIGNAL(currentChanged(int)), d, SLOT(toggleArea(int))); } MainWindow::~MainWindow() { kDebug() << "destroying mainwindow"; delete d; } void MainWindow::setArea(Area *area) { if (d->area) disconnect(d->area, 0, this, 0); bool wasEnabled = updatesEnabled(); setUpdatesEnabled(false); bool differentArea = (area != d->area); /* All views will be removed from dock area now. However, this does not mean those are removed from area, so prevent slotDockShown from recording those views as no longer shown in the area. */ d->ignoreDockShown = true; if (d->autoAreaSettingsSave && differentArea) saveSettings(); if (d->area) clearArea(); d->area = area; d->reconstruct(); if(d->area->activeView()) activateView(d->area->activeView()); else d->activateFirstVisibleView(); initializeStatusBar(); emit areaChanged(area); d->ignoreDockShown = false; setUpdatesEnabled(wasEnabled); // delay loading settings: we need to finish with area activation // and only then load mainwindow/dockwidget settings // this way dock sizes get properly restored QMetaObject::invokeMethod(this, "loadSettings", Qt::QueuedConnection); connect(area, SIGNAL(viewAdded(Sublime::AreaIndex*, Sublime::View*)), this, SLOT(viewAdded(Sublime::AreaIndex*, Sublime::View*))); connect(area, SIGNAL(viewRemoved(Sublime::AreaIndex*,Sublime::View*)), this, SLOT(viewRemovedInternal(Sublime::AreaIndex*, Sublime::View*))); connect(area, SIGNAL(requestToolViewRaise(Sublime::View*)), this, SLOT(raiseToolView(Sublime::View*))); connect(area, SIGNAL(aboutToRemoveView(Sublime::AreaIndex*, Sublime::View*)), this, SLOT(aboutToRemoveView(Sublime::AreaIndex*, Sublime::View*))); connect(area, SIGNAL(toolViewAdded(Sublime::View*, Sublime::Position)), this, SLOT(toolViewAdded(Sublime::View*, Sublime::Position))); connect(area, SIGNAL(aboutToRemoveToolView(Sublime::View*, Sublime::Position)), this, SLOT(aboutToRemoveToolView(Sublime::View*, Sublime::Position))); connect(area, SIGNAL(toolViewMoved(Sublime::View*, Sublime::Position)), this, SLOT(toolViewMoved(Sublime::View*, Sublime::Position))); connect(area, SIGNAL(changedWorkingSet(Sublime::Area*,QString,QString)), this, SLOT(setupAreaSelector())); } void MainWindow::initializeStatusBar() { //nothing here, reimplement in the subclasses if you want to have status bar //inside the bottom toolview buttons row } void MainWindow::resizeEvent(QResizeEvent* event) { return KParts::MainWindow::resizeEvent(event); } void MainWindow::clearArea() { emit areaCleared(d->area); d->clearArea(); } QList MainWindow::toolDocks() const { return d->docks; } Area *Sublime::MainWindow::area() const { return d->area; } Controller *MainWindow::controller() const { return d->controller; } View *MainWindow::activeView() { return d->activeView; } View *MainWindow::activeToolView() { return d->activeToolView; } void MainWindow::activateView(View *view) { if (!d->viewContainers.contains(view)) return; d->viewContainers[view]->setCurrentWidget(view->widget()); setActiveView(view); d->area->setActiveView(view); } void MainWindow::setActiveView(View *view) { View* oldActiveView = d->activeView; d->activeView = view; if (view && !view->widget()->hasFocus()) view->widget()->setFocus(); if(d->activeView != oldActiveView) emit activeViewChanged(view); } void Sublime::MainWindow::setActiveToolView(View *view) { d->activeToolView = view; emit activeToolViewChanged(view); } void MainWindow::saveSettings() { QString group = "MainWindow"; if (area()) group += '_' + area()->objectName(); KConfigGroup cg = KGlobal::config()->group(group); /* This will try to save window size, too. But it's OK, since we won't use this information when loading. */ saveMainWindowSettings(cg); //debugToolBar visibility is stored separately to allow a area dependent default value foreach (KToolBar* toolbar, toolBars()) { if (toolbar->objectName() == "debugToolBar") { - cg.writeEntry("debugToolBarVisibility", toolbar->isVisible()); + cg.writeEntry("debugToolBarVisibility", toolbar->isVisibleTo(this)); } } cg.sync(); } void MainWindow::loadSettings() { setUpdatesEnabled(false); kDebug(9504) << "loading settings for " << (area() ? area()->objectName() : ""); QString group = "MainWindow"; if (area()) group += '_' + area()->objectName(); KConfigGroup cg = KGlobal::config()->group(group); // What follows is copy-paste from applyMainWindowSettings. Unfortunately, // we don't really want that one to try restoring window size, and we also // cannot stop it from doing that in any clean way. QStatusBar* sb = qFindChild(this); if (sb) { QString entry = cg.readEntry("StatusBar", "Enabled"); if ( entry == "Disabled" ) sb->hide(); else sb->show(); } QMenuBar* mb = qFindChild(this); if (mb) { QString entry = cg.readEntry ("MenuBar", "Enabled"); if ( entry == "Disabled" ) mb->hide(); else mb->show(); } if ( !autoSaveSettings() || cg.name() == autoSaveGroup() ) { QString entry = cg.readEntry ("ToolBarsMovable", "Enabled"); if ( entry == "Disabled" ) KToolBar::setToolBarsLocked(true); else KToolBar::setToolBarsLocked(false); } // Utilise the QMainWindow::restoreState() functionality // Note that we're fixing KMainWindow bug here -- the original // code has this fragment above restoring toolbar properties. // As result, each save/restore would move the toolbar a bit to // the left. if (cg.hasKey("State")) { QByteArray state; state = cg.readEntry("State", state); state = QByteArray::fromBase64(state); // One day will need to load the version number, but for now, assume 0 restoreState(state); } else { // If there's no state we use a default size of 870x650 // Resize only when showing "code" area. If we do that for other areas, // then we'll hit bug https://bugs.kde.org/show_bug.cgi?id=207990 // TODO: adymo: this is more like a hack, we need a proper first-start initialization if (area() && area()->objectName() == "code") resize(870,650); } int n = 1; // Toolbar counter. toolbars are counted from 1, foreach (KToolBar* toolbar, toolBars()) { QString group("Toolbar"); // Give a number to the toolbar, but prefer a name if there is one, // because there's no real guarantee on the ordering of toolbars group += (toolbar->objectName().isEmpty() ? QString::number(n) : QString(" ")+toolbar->objectName()); KConfigGroup toolbarGroup(&cg, group); toolbar->applySettings(toolbarGroup, false); if (toolbar->objectName() == "debugToolBar") { //debugToolBar visibility is stored separately to allow a area dependent default value bool visibility = cg.readEntry("debugToolBarVisibility", area()->objectName() == "debug"); toolbar->setVisible(visibility); } n++; } KConfigGroup uiGroup = KGlobal::config()->group("UiSettings"); foreach (Container *container, findChildren()) { container->setTabBarHidden(uiGroup.readEntry("TabBarVisibility", 1) == 0); } cg.sync(); setUpdatesEnabled(true); emit settingsLoaded(); } bool MainWindow::queryClose() { // saveSettings(); KConfigGroup config(KGlobal::config(), "Main Window"); saveGeometry(config); config.sync(); return KParts::MainWindow::queryClose(); } void MainWindow::saveGeometry(KConfigGroup &config) { int scnum = QApplication::desktop()->screenNumber(parentWidget()); QRect desk = QApplication::desktop()->screenGeometry(scnum); // if the desktop is virtual then use virtual screen size if (QApplication::desktop()->isVirtualDesktop()) desk = QApplication::desktop()->screenGeometry(QApplication::desktop()->screen()); QString key = QString::fromLatin1("Desktop %1 %2") .arg(desk.width()).arg(desk.height()); config.writeEntry(key, geometry()); } void MainWindow::loadGeometry(const KConfigGroup &config) { // The below code, essentially, is copy-paste from // KMainWindow::restoreWindowSize. Right now, that code is buggy, // as per http://permalink.gmane.org/gmane.comp.kde.devel.core/52423 // so we implement a less theoretically correct, but working, version // below const int scnum = QApplication::desktop()->screenNumber(parentWidget()); QRect desk = QApplication::desktop()->screenGeometry(scnum); // if the desktop is virtual then use virtual screen size if (QApplication::desktop()->isVirtualDesktop()) desk = QApplication::desktop()->screenGeometry(QApplication::desktop()->screen()); QString key = QString::fromLatin1("Desktop %1 %2") .arg(desk.width()).arg(desk.height()); QRect g = config.readEntry(key, QRect()); if (!g.isEmpty()) setGeometry(g); } void MainWindow::enableAreaSettingsSave() { d->autoAreaSettingsSave = true; } QWidget *MainWindow::statusBarLocation() { return d->idealController->statusBarLocation(); } void MainWindow::setAreaSwitcherCornerWidget(QWidget* widget) { d->areaSwitcher->setTabSideWidget(widget); } void MainWindow::setTabBarLeftCornerWidget(QWidget* widget) { d->setTabBarLeftCornerWidget(widget); } void MainWindow::tabContextMenuRequested(View* , KMenu* ) { // do nothing } void MainWindow::tabToolTipRequested(View*, Container*, int) { // do nothing } void MainWindow::dockBarContextMenuRequested(Qt::DockWidgetArea , const QPoint& ) { // do nothing } View* MainWindow::viewForPosition(QPoint globalPos) const { foreach(Container* container, d->viewContainers.values()) { QRect globalGeom = QRect(container->mapToGlobal(QPoint(0,0)), container->mapToGlobal(QPoint(container->width(), container->height()))); if(globalGeom.contains(globalPos)) { return d->widgetToView[container->currentWidget()]; } } return 0; } } #include "mainwindow.moc" diff --git a/vcs/widgets/vcsdiffpatchsources.cpp b/vcs/widgets/vcsdiffpatchsources.cpp index bfcd6c8e1b..66ade13b09 100644 --- a/vcs/widgets/vcsdiffpatchsources.cpp +++ b/vcs/widgets/vcsdiffpatchsources.cpp @@ -1,274 +1,275 @@ /* Copyright 2009 David Nolden This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "vcsdiffpatchsources.h" #include #include #include #include #include #include #include #include #include "vcsjob.h" #include "vcsdiff.h" #include #include #include #include using namespace KDevelop; VCSCommitDiffPatchSource::VCSCommitDiffPatchSource(VCSDiffUpdater* updater, const KUrl& url, IBasicVersionControl* vcs) : VCSDiffPatchSource(updater), m_vcs(vcs) { Q_ASSERT(m_vcs); QScopedPointer statusJob(vcs->status(url)); QVariant varlist; if( statusJob->exec() && statusJob->status() == VcsJob::JobSucceeded ) { varlist = statusJob->fetchResults(); foreach( const QVariant &var, varlist.toList() ) { VcsStatusInfo info = qVariantValue( var ); m_infos += info; if(info.state()!=VcsStatusInfo::ItemUpToDate) m_selectable[info.url()] = info.state(); } } else kDebug() << "Couldn't get status for urls: " << url; m_commitMessageWidget = new QWidget; QVBoxLayout* layout = new QVBoxLayout(m_commitMessageWidget.data()); m_commitMessageEdit = new QTextEdit; m_commitMessageEdit.data()->setFont( KGlobalSettings::fixedFont() ); + m_commitMessageEdit.data()->setLineWrapMode(QTextEdit::NoWrap); QHBoxLayout* titleLayout = new QHBoxLayout; titleLayout->addWidget(new QLabel(i18n("Commit Message:"))); m_oldMessages = new KComboBox; m_oldMessages->addItem(i18n("Old Messages")); foreach(QString message, oldMessages()) m_oldMessages->addItem(message, message); m_oldMessages->setMaximumWidth(200); connect(m_oldMessages, SIGNAL(currentIndexChanged(QString)), this, SLOT(oldMessageChanged(QString))); titleLayout->addWidget(m_oldMessages); layout->addLayout(titleLayout); layout->addWidget(m_commitMessageEdit.data()); } QStringList VCSCommitDiffPatchSource::oldMessages() const { KConfigGroup vcsGroup(ICore::self()->activeSession()->config(), "VCS"); return vcsGroup.readEntry("OldCommitMessages", QStringList()); } void VCSCommitDiffPatchSource::oldMessageChanged(QString text) { if(m_oldMessages->currentIndex() != 0) { m_oldMessages->setCurrentIndex(0); m_commitMessageEdit.data()->setText(text); } } VCSDiffPatchSource::VCSDiffPatchSource(VCSDiffUpdater* updater) : m_updater(updater) { update(); } VCSDiffPatchSource::VCSDiffPatchSource(const KDevelop::VcsDiff& diff) : m_updater(0) { updateFromDiff(diff); } VCSDiffPatchSource::~VCSDiffPatchSource() { QFile::remove(m_file.toLocalFile()); delete m_updater; } KUrl VCSDiffPatchSource::baseDir() const { return m_base; } KUrl VCSDiffPatchSource::file() const { return m_file; } QString VCSDiffPatchSource::name() const { return m_name; } void VCSDiffPatchSource::updateFromDiff(VcsDiff vcsdiff) { if(!m_file.isValid()) { KTemporaryFile temp2; temp2.setSuffix("2.patch"); temp2.setAutoRemove(false); temp2.open(); QTextStream t2(&temp2); t2 << vcsdiff.diff(); kDebug() << "filename:" << temp2.fileName(); m_file = KUrl(temp2.fileName()); temp2.close(); }else{ QFile file(m_file.path()); file.open(QIODevice::WriteOnly); QTextStream t2(&file); t2 << vcsdiff.diff(); } kDebug() << "using file" << m_file << vcsdiff.diff(); m_name = "VCS Diff"; m_base = vcsdiff.baseDiff(); emit patchChanged(); } void VCSDiffPatchSource::update() { if(!m_updater) return; updateFromDiff(m_updater->update()); } VCSCommitDiffPatchSource::~VCSCommitDiffPatchSource() { delete m_commitMessageWidget.data(); } bool VCSCommitDiffPatchSource::canSelectFiles() const { return true; } QMap< KUrl, KDevelop::VcsStatusInfo::State> VCSCommitDiffPatchSource::additionalSelectableFiles() const { return m_selectable; } QWidget* VCSCommitDiffPatchSource::customWidget() const { return m_commitMessageWidget.data(); } QString VCSCommitDiffPatchSource::finishReviewCustomText() const { return i18n("Commit"); } bool VCSCommitDiffPatchSource::canCancel() const { return true; } void VCSCommitDiffPatchSource::cancelReview() { QString message; if (m_commitMessageEdit) message = m_commitMessageEdit.data()->toPlainText(); emit reviewCancelled(message); deleteLater(); } bool VCSCommitDiffPatchSource::finishReview(QList< KUrl > selection) { QString message; if (m_commitMessageEdit) message = m_commitMessageEdit.data()->toPlainText(); kDebug() << "Finishing with selection" << selection; QString text = i18n("Files will be committed:\n"); foreach(const KUrl& url, selection) text += ICore::self()->projectController()->prettyFileName(url, KDevelop::IProjectController::FormatPlain) + '\n'; text += i18n("\nWith message:\n %1", message); int res = KMessageBox::warningContinueCancel(0, text, i18n("About to commit to repository")); if (res != KMessageBox::Continue) { return false; } emit reviewFinished(message, selection); VcsJob* job=m_vcs->commit(message, selection, KDevelop::IBasicVersionControl::NonRecursive); ICore::self()->runController()->registerJob(job); deleteLater(); return true; } static KDevelop::IPatchSource::Ptr currentShownDiff; bool showVcsDiff(IPatchSource* vcsDiff) { KDevelop::IPatchReview* patchReview = ICore::self()->pluginController()->extensionForPlugin("org.kdevelop.IPatchReview"); //Only give one VCS diff at a time to the patch review plugin delete currentShownDiff; currentShownDiff = vcsDiff; if( patchReview ) { patchReview->startReview(currentShownDiff); return true; } else { kWarning() << "Patch review plugin not found"; return false; } } VcsDiff VCSStandardDiffUpdater::update() const { QScopedPointer diffJob(m_vcs->diff(m_url, KDevelop::VcsRevision::createSpecialRevision(KDevelop::VcsRevision::Base), KDevelop::VcsRevision::createSpecialRevision(KDevelop::VcsRevision::Working))); VcsDiff diff; bool correctDiff = diffJob->exec(); if (correctDiff) diff = diffJob->fetchResults().value(); if (!correctDiff) KMessageBox::error(0, i18n("Could not create a patch for the current version.")); return diff; } VCSStandardDiffUpdater::VCSStandardDiffUpdater(IBasicVersionControl* vcs, KUrl url) : m_vcs(vcs), m_url(url) { } VCSStandardDiffUpdater::~VCSStandardDiffUpdater() { } VCSDiffUpdater::~VCSDiffUpdater() { } #include "vcsdiffpatchsources.moc"