File indexing completed on 2024-04-28 17:00:47
0001 /*************************************************************************** 0002 * Copyright (C) 2005-2009 by Rajko Albrecht * 0003 * ral@alwins-world.de * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 0019 ***************************************************************************/ 0020 0021 #include "kdesvn.h" 0022 #include "urldlg.h" 0023 #include "kdesvn_part.h" 0024 #include "helpers/ktranslateurl.h" 0025 #include "helpers/kdesvn_debug.h" 0026 0027 #include <QApplication> 0028 #include <QDir> 0029 #include <QMenuBar> 0030 #include <QStatusBar> 0031 #include <QTimer> 0032 0033 #include <ksharedconfig.h> 0034 #include <kconfig.h> 0035 #include <kconfiggroup.h> 0036 #include <khelpmenu.h> 0037 #include <KActionCollection> 0038 #include <KBookmarkManager> 0039 #include <KLocalizedString> 0040 #include <KMessageBox> 0041 #include <KPluginFactory> 0042 #include <KPluginLoader> 0043 #include <KRecentFilesAction> 0044 #include <KStandardAction> 0045 #include <KToggleAction> 0046 #include <KEditToolBar> 0047 #include <KShortcutsDialog> 0048 0049 #ifdef TESTING_RC 0050 #include <kcrash.h> 0051 #endif 0052 0053 kdesvn::kdesvn() 0054 : KParts::MainWindow(), 0055 KBookmarkOwner() 0056 { 0057 setAttribute(Qt::WA_DeleteOnClose); 0058 m_part = nullptr; 0059 #ifdef TESTING_RC 0060 setXMLFile(TESTING_RC); 0061 qCDebug(KDESVN_LOG) << "Using test rc file in " << TESTING_RC << endl; 0062 // I hate this crashhandler in development 0063 KCrash::setCrashHandler(0); 0064 #else 0065 setXMLFile(QStringLiteral("kdesvnui.rc")); 0066 #endif 0067 setStandardToolBarMenuEnabled(true); 0068 // then, setup our actions 0069 setupActions(); 0070 // and a status bar 0071 statusBar()->show(); 0072 0073 QDir bookmarkDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); 0074 if (!bookmarkDir.exists()) { 0075 bookmarkDir.mkpath(bookmarkDir.absolutePath()); 0076 } 0077 0078 m_bookmarkFile = bookmarkDir.absolutePath()+ QLatin1String("/bookmarks.xml"); 0079 m_BookmarkManager = KBookmarkManager::managerForExternalFile(m_bookmarkFile); 0080 m_BookmarksActionmenu = new KBookmarkActionMenu(m_BookmarkManager->root(), 0081 i18n("&Bookmarks"), this); 0082 0083 actionCollection()->addAction(QStringLiteral("bookmarks"), m_BookmarksActionmenu); 0084 m_Bookmarkactions = new KActionCollection(static_cast<QWidget *>(this)); 0085 m_pBookmarkMenu = new KBookmarkMenu(m_BookmarkManager, this, m_BookmarksActionmenu->menu(), m_Bookmarkactions); 0086 m_pBookmarkMenu->setParent(this); // clear when kdesvn window gets destroyed 0087 0088 #ifdef EXTRA_KDE_LIBPATH 0089 QCoreApplication::addLibraryPath(QString::fromLocal8Bit(EXTRA_KDE_LIBPATH)) 0090 #endif 0091 // this routine will find and load our Part. it finds the Part by 0092 // name which is a bad idea usually.. but it's alright in this 0093 // case since our Part is made for this Shell 0094 KPluginLoader loader(QStringLiteral("kdesvnpart")); 0095 KPluginFactory *factory = loader.factory(); 0096 if (factory) { 0097 m_part = factory->create<KParts::ReadOnlyPart>(this); 0098 if (m_part) { 0099 // tell the KParts::MainWindow that this is indeed the main widget 0100 setCentralWidget(m_part->widget()); 0101 connect(this, SIGNAL(sigSavestate()), m_part->widget(), SLOT(slotSavestate())); 0102 connect(m_part->widget(), SIGNAL(sigExtraStatusMessage(QString)), this, SLOT(slotExtraStatus(QString))); 0103 connect(m_part->widget(), SIGNAL(sigUrlOpened(bool)), this, SLOT(slotUrlOpened(bool))); 0104 0105 QAction *tmpAction; 0106 tmpAction = actionCollection()->addAction(QStringLiteral("subversion_create_repo"), 0107 m_part->widget(), 0108 SLOT(slotCreateRepo())); 0109 tmpAction->setText(i18n("Create and open new repository")); 0110 tmpAction->setToolTip(i18n("Create and opens a new local Subversion repository")); 0111 0112 tmpAction = actionCollection()->addAction(QStringLiteral("subversion_dump_repo"), 0113 m_part->widget(), 0114 SLOT(slotDumpRepo())); 0115 tmpAction->setText(i18n("Dump repository to file")); 0116 tmpAction->setToolTip(i18n("Dump a Subversion repository to a file")); 0117 0118 tmpAction = actionCollection()->addAction(QStringLiteral("subversion_hotcopy_repo"), 0119 m_part->widget(), 0120 SLOT(slotHotcopy())); 0121 tmpAction->setText(i18n("Hotcopy a repository")); 0122 tmpAction->setToolTip(i18n("Hotcopy a Subversion repository to a new folder")); 0123 0124 tmpAction = actionCollection()->addAction(QStringLiteral("subversion_load_repo"), 0125 m_part->widget(), 0126 SLOT(slotLoaddump())); 0127 tmpAction->setText(i18n("Load dump into repository")); 0128 tmpAction->setToolTip(i18n("Load a dump file into a repository.")); 0129 0130 tmpAction = actionCollection()->addAction(QStringLiteral("kdesvn_ssh_add"), 0131 m_part, 0132 SLOT(slotSshAdd())); 0133 tmpAction->setText(i18n("Add ssh identities to ssh-agent")); 0134 tmpAction->setToolTip(i18n("Force add ssh-identities to ssh-agent for future use.")); 0135 0136 tmpAction = actionCollection()->addAction(QStringLiteral("help_about_kdesvnpart"), 0137 m_part, 0138 SLOT(showAboutApplication())); 0139 tmpAction->setText(i18n("Info about kdesvn part")); 0140 tmpAction->setToolTip(i18n("Shows info about the kdesvn plugin and not the standalone application.")); 0141 0142 tmpAction = actionCollection()->addAction(QStringLiteral("db_show_status"), 0143 m_part, 0144 SLOT(showDbStatus())); 0145 tmpAction->setText(i18n("Show database content")); 0146 tmpAction->setToolTip(i18n("Show the content of log cache database")); 0147 0148 // and integrate the part's GUI with the shells 0149 createGUI(m_part); 0150 0151 } else { 0152 KMessageBox::error(this, i18n("Could not load the part:\n%1", loader.errorString())); 0153 qApp->quit(); 0154 return; 0155 } 0156 } else { 0157 // if we couldn't find our Part, we exit since the Shell by 0158 // itself can't do anything useful 0159 KMessageBox::error(this, i18n("Could not find our part:\n%1", loader.errorString())); 0160 qApp->quit(); 0161 // we return here, cause kapp->quit() only means "exit the 0162 // next time we enter the event loop... 0163 return; 0164 } 0165 setAutoSaveSettings(); 0166 } 0167 0168 kdesvn::~kdesvn() 0169 { 0170 } 0171 0172 void kdesvn::loadRescent(const QUrl &url) 0173 { 0174 load(url, true); 0175 } 0176 0177 void kdesvn::load(const QUrl &url, bool addRescent) 0178 { 0179 QTimer::singleShot(100, this, &kdesvn::slotResetExtraStatus); 0180 if (m_part) { 0181 bool ret = m_part->openUrl(url); 0182 KRecentFilesAction *rac = nullptr; 0183 if (addRescent) { 0184 QAction *ac = actionCollection()->action(QStringLiteral("file_open_recent")); 0185 if (ac) { 0186 rac = (KRecentFilesAction *)ac; 0187 } 0188 } 0189 if (!ret) { 0190 changeStatusbar(i18n("Could not open URL %1", url.toString())); 0191 if (rac) { 0192 rac->removeUrl(url); 0193 } 0194 } else { 0195 resetStatusBar(); 0196 if (rac) { 0197 rac->addUrl(url); 0198 } 0199 } 0200 if (rac) { 0201 KConfigGroup cg(KSharedConfig::openConfig(), "recent_files"); 0202 rac->saveEntries(cg); 0203 } 0204 } 0205 } 0206 0207 void kdesvn::setupActions() 0208 { 0209 QAction *ac; 0210 KStandardAction::open(this, SLOT(fileOpen()), actionCollection()); 0211 KStandardAction::openNew(this, SLOT(fileNew()), actionCollection()); 0212 ac = KStandardAction::close(this, SLOT(fileClose()), actionCollection()); 0213 // ac->setEnabled(getMemberList()->count()>1); 0214 ac->setEnabled(memberList().count() > 1); 0215 KStandardAction::quit(this, SLOT(close()), actionCollection()); 0216 0217 KRecentFilesAction *rac = KStandardAction::openRecent(this, SLOT(loadRescent(QUrl)), actionCollection()); 0218 if (rac) { 0219 rac->setMaxItems(8); 0220 KConfigGroup cg(KSharedConfig::openConfig(), "recent_files"); 0221 rac->loadEntries(cg); 0222 rac->setText(i18n("Recent opened URLs")); 0223 } 0224 0225 KStandardAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection()); 0226 KStandardAction::configureToolbars(this, SLOT(optionsConfigureToolbars()), actionCollection()); 0227 0228 m_statusbarAction = KStandardAction::showStatusbar(this, SLOT(optionsShowStatusbar()), actionCollection()); 0229 0230 KToggleAction *toggletemp; 0231 toggletemp = new KToggleAction(i18n("Load last opened URL on start"), this); 0232 actionCollection()->addAction(QStringLiteral("toggle_load_last_url"), toggletemp); 0233 toggletemp->setToolTip(i18n("Reload last opened URL if no one is given on command line")); 0234 KConfigGroup cs(KSharedConfig::openConfig(), "startup"); 0235 toggletemp->setChecked(cs.readEntry("load_last_on_start", false)); 0236 connect(toggletemp, &QAction::toggled, this, &kdesvn::slotLoadLast); 0237 } 0238 0239 void kdesvn::optionsShowStatusbar() 0240 { 0241 // this is all very cut and paste code for showing/hiding the 0242 // statusbar 0243 statusBar()->setVisible(m_statusbarAction->isChecked()); 0244 } 0245 0246 void kdesvn::fileClose() 0247 { 0248 if (m_part) { 0249 m_part->closeUrl(); 0250 } 0251 // if (getMemberList()->count()>1) { 0252 if (memberList().count() > 1) { 0253 close(); 0254 } else { 0255 enableClose(false); 0256 QTimer::singleShot(100, this, &kdesvn::slotResetExtraStatus); 0257 enableClose(false); 0258 } 0259 } 0260 0261 void kdesvn::saveProperties(KConfigGroup &config) 0262 { 0263 // the 'config' object points to the session managed 0264 // config file. anything you write here will be available 0265 // later when this app is restored 0266 if (!m_part) { 0267 return; 0268 } 0269 if (!m_part->url().isEmpty()) { 0270 config.writeEntry("lastURL", m_part->url().toString()); 0271 } 0272 } 0273 0274 void kdesvn::readProperties(const KConfigGroup &config) 0275 { 0276 // the 'config' object points to the session managed 0277 // config file. this function is automatically called whenever 0278 // the app is being restored. read in here whatever you wrote 0279 // in 'saveProperties' 0280 if (!m_part) { 0281 return; 0282 } 0283 0284 const QUrl url(config.readPathEntry("lastURL", QString())); 0285 if (url.isValid()) { 0286 m_part->openUrl(url); 0287 } 0288 } 0289 0290 void kdesvn::fileNew() 0291 { 0292 // this slot is called whenever the File->New menu is selected, 0293 // the New shortcut is pressed (usually CTRL+N) or the New toolbar 0294 // button is clicked 0295 0296 // create a new window 0297 (new kdesvn)->show(); 0298 enableClose(true); 0299 } 0300 0301 void kdesvn::fileOpen() 0302 { 0303 QUrl url = UrlDlg::getUrl(this); 0304 if (!url.isEmpty()) { 0305 load(url, true); 0306 } 0307 } 0308 0309 void kdesvn::changeStatusbar(const QString &text) 0310 { 0311 statusBar()->showMessage(text); 0312 } 0313 0314 void kdesvn::resetStatusBar() 0315 { 0316 statusBar()->showMessage(i18n("Ready"), 4000); 0317 } 0318 0319 // kde4 port - pv 0320 void kdesvn::openBookmark(const KBookmark &bm, Qt::MouseButtons mb, Qt::KeyboardModifiers km) 0321 { 0322 Q_UNUSED(mb); 0323 Q_UNUSED(km); 0324 if (!bm.url().isEmpty() && m_part) { 0325 load(bm.url(), false); 0326 } 0327 } 0328 0329 QUrl kdesvn::currentUrl() const 0330 { 0331 if (!m_part) { 0332 return QUrl(); 0333 } 0334 return m_part->url(); 0335 } 0336 0337 QString kdesvn::currentTitle() const 0338 { 0339 if (!m_part) { 0340 return QString(); 0341 } 0342 return m_part->url().fileName(); 0343 } 0344 0345 void kdesvn::enableClose(bool how) 0346 { 0347 QAction *ac; 0348 if ((ac = actionCollection()->action(QStringLiteral("file_close")))) { 0349 ac->setEnabled(how); 0350 } 0351 } 0352 0353 /*! 0354 \fn kdesvn::slotUrlOpened(bool) 0355 */ 0356 void kdesvn::slotUrlOpened(bool how) 0357 { 0358 enableClose(how); 0359 } 0360 0361 /*! 0362 \fn kdesvn::optionsConfigureToolbars() 0363 */ 0364 void kdesvn::optionsConfigureToolbars() 0365 { 0366 KConfigGroup cg(KSharedConfig::openConfig(), autoSaveGroup()); 0367 saveMainWindowSettings(cg); 0368 0369 // use the standard toolbar editor 0370 QPointer<KEditToolBar> dlg(new KEditToolBar(factory())); 0371 connect(dlg.data(), &KEditToolBar::newToolbarConfig, 0372 this, &kdesvn::applyNewToolbarConfig); 0373 dlg->exec(); 0374 delete dlg; 0375 } 0376 0377 /*! 0378 \fn kdesvn::applyNewToolbarConfig() 0379 */ 0380 void kdesvn::applyNewToolbarConfig() 0381 { 0382 KConfigGroup cg(KSharedConfig::openConfig(), autoSaveGroup()); 0383 applyMainWindowSettings(cg); 0384 } 0385 0386 void kdesvn::optionsConfigureKeys() 0387 { 0388 QPointer<KShortcutsDialog> kdlg(new KShortcutsDialog(KShortcutsEditor::AllActions, 0389 KShortcutsEditor::LetterShortcutsAllowed, 0390 m_part->widget())); 0391 kdlg->addCollection(actionCollection()); 0392 kdlg->addCollection(m_part->actionCollection()); 0393 0394 kdlg->configure(true); 0395 delete kdlg; 0396 } 0397 0398 /*! 0399 \fn kdesvn::closeEvent() 0400 */ 0401 void kdesvn::closeEvent(QCloseEvent *ev) 0402 { 0403 emit sigSavestate(); 0404 if (m_part) { 0405 KConfigGroup cs(KSharedConfig::openConfig(), "startup"); 0406 cs.writeEntry("lastURL", m_part->url().toString(QUrl::FullyEncoded)); 0407 cs.sync(); 0408 } 0409 return KParts::MainWindow::closeEvent(ev); 0410 } 0411 0412 /*! 0413 \fn kdesvn::checkReload() 0414 */ 0415 void kdesvn::checkReload() 0416 { 0417 KConfigGroup cs(KSharedConfig::openConfig(), "startup"); 0418 if (!cs.readEntry("load_last_on_start", false)) { 0419 return; 0420 } 0421 0422 const QUrl url(cs.readPathEntry("lastURL", QString())); 0423 if (url.isValid() && m_part) { 0424 load(url, false); 0425 } 0426 } 0427 0428 /*! 0429 \fn kdesvn::slotLoadLast(bool) 0430 */ 0431 void kdesvn::slotLoadLast(bool how) 0432 { 0433 KConfigGroup cs(KSharedConfig::openConfig(), "startup"); 0434 cs.writeEntry("load_last_on_start", how); 0435 cs.sync(); 0436 } 0437 0438 void kdesvn::slotResetExtraStatus() 0439 { 0440 statusBar()->clearMessage(); 0441 } 0442 0443 void kdesvn::slotExtraStatus(const QString &message) 0444 { 0445 statusBar()->clearMessage(); 0446 statusBar()->showMessage(message); 0447 }