Warning, file /utilities/krusader/app/KViewer/krviewer.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2002 Shie Erlich <erlich@users.sourceforge.net> 0003 SPDX-FileCopyrightText: 2002 Rafi Yanai <yanai@users.sourceforge.net> 0004 SPDX-FileCopyrightText: 2004-2022 Krusader Krew <https://krusader.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "krviewer.h" 0010 0011 // QtCore 0012 #include <QDataStream> 0013 #include <QDebug> 0014 #include <QEvent> 0015 #include <QFile> 0016 #include <QTimer> 0017 // QtGui 0018 #include <QKeyEvent> 0019 // QtWidgets 0020 #include <QMenuBar> 0021 #include <QStatusBar> 0022 0023 #include <KConfigCore/KSharedConfig> 0024 #include <KConfigWidgets/KStandardAction> 0025 #include <KCoreAddons/KProcess> 0026 #include <KCoreAddons/KShell> 0027 #include <KI18n/KLocalizedString> 0028 #include <KIOCore/KFileItem> 0029 #include <KParts/Part> 0030 #include <KWidgetsAddons/KMessageBox> 0031 #include <KXmlGui/KActionCollection> 0032 #include <KXmlGui/KShortcutsDialog> 0033 #include <KXmlGui/KToolBar> 0034 #include <kxmlgui_version.h> 0035 #include <utility> 0036 0037 #include "../defaults.h" 0038 #include "../icon.h" 0039 #include "panelviewer.h" 0040 #include "viewertabbar.h" 0041 0042 #define VIEW_ICON "document-preview" 0043 #define EDIT_ICON "document-edit" 0044 #define MODIFIED_ICON "document-save-as" 0045 0046 #define CHECK_MODFIED_INTERVAL 500 0047 0048 /* 0049 NOTE: Currently the code expects PanelViewer::openUrl() to be called only once 0050 in the panel viewer's life time - otherwise unexpected things might happen. 0051 */ 0052 0053 QList<KrViewer *> KrViewer::viewers; 0054 0055 KrViewer::KrViewer(QWidget *parent) 0056 : KParts::MainWindow(parent, Qt::WindowFlags()) 0057 , manager(this, this) 0058 , tabWidget(this) 0059 , sizeX(-1) 0060 , sizeY(-1) 0061 { 0062 // setWFlags(Qt::WType_TopLevel | WDestructiveClose); 0063 setXMLFile("krviewer.rc"); // kpart-related xml file 0064 setHelpMenuEnabled(false); 0065 0066 connect(&manager, &KParts::PartManager::activePartChanged, this, &KrViewer::createGUI); 0067 connect(&tabWidget, &QTabWidget::currentChanged, this, &KrViewer::tabChanged); 0068 connect(&tabWidget, &QTabWidget::tabCloseRequested, this, [=](int index) { 0069 tabCloseRequest(index, false); 0070 }); 0071 0072 tabWidget.setDocumentMode(true); 0073 tabWidget.setMovable(true); 0074 if (ViewerTabBar *tabBar = tabWidget.tabBar()) 0075 connect(tabBar, &ViewerTabBar::closeTabSignal, this, [=](int index) { 0076 tabCloseRequest(index, false); 0077 }); 0078 setCentralWidget(&tabWidget); 0079 0080 printAction = KStandardAction::print(this, SLOT(print()), nullptr); 0081 copyAction = KStandardAction::copy(this, SLOT(copy()), nullptr); 0082 0083 viewerMenu = new QMenu(this); 0084 QAction *tempAction; 0085 KActionCollection *ac = actionCollection(); 0086 0087 #define addCustomMenuAction(name, text, slot, shortcut) \ 0088 tempAction = ac->addAction(name, this, slot); \ 0089 tempAction->setText(text); \ 0090 ac->setDefaultShortcut(tempAction, shortcut); \ 0091 viewerMenu->addAction(tempAction); 0092 0093 addCustomMenuAction("genericViewer", i18n("&Generic Viewer"), SLOT(viewGeneric()), Qt::CTRL + Qt::SHIFT + Qt::Key_G); 0094 addCustomMenuAction("textViewer", i18n("&Text Viewer"), SLOT(viewText()), Qt::CTRL + Qt::SHIFT + Qt::Key_T); 0095 addCustomMenuAction("hexViewer", i18n("&Hex Viewer"), SLOT(viewHex()), Qt::CTRL + Qt::SHIFT + Qt::Key_H); 0096 addCustomMenuAction("lister", i18n("&Lister"), SLOT(viewLister()), Qt::CTRL + Qt::SHIFT + Qt::Key_L); 0097 viewerMenu->addSeparator(); 0098 0099 addCustomMenuAction("textEditor", i18n("Text &Editor"), SLOT(editText()), Qt::CTRL + Qt::SHIFT + Qt::Key_E); 0100 viewerMenu->addSeparator(); 0101 0102 QList<QAction *> actList = menuBar()->actions(); 0103 bool hasPrint = false, hasCopy = false; 0104 foreach (QAction *a, actList) { 0105 if (a->shortcut().matches(printAction->shortcut()) != QKeySequence::NoMatch) 0106 hasPrint = true; 0107 if (a->shortcut().matches(copyAction->shortcut()) != QKeySequence::NoMatch) 0108 hasCopy = true; 0109 } 0110 QAction *printAct = viewerMenu->addAction(printAction->icon(), printAction->text(), this, SLOT(print())); 0111 if (hasPrint) 0112 printAct->setShortcut(printAction->shortcut()); 0113 QAction *copyAct = viewerMenu->addAction(copyAction->icon(), copyAction->text(), this, SLOT(copy())); 0114 if (hasCopy) 0115 copyAct->setShortcut(copyAction->shortcut()); 0116 viewerMenu->addSeparator(); 0117 0118 configKeysAction = ac->addAction(KStandardAction::KeyBindings, this, SLOT(configureShortcuts())); 0119 viewerMenu->addAction(configKeysAction); 0120 viewerMenu->addSeparator(); 0121 0122 detachAction = ac->addAction("detachTab", this, SLOT(detachTab())); 0123 detachAction->setText(i18n("&Detach Tab")); 0124 // no point in detaching only one tab.. 0125 detachAction->setEnabled(false); 0126 ac->setDefaultShortcut(detachAction, Qt::META + Qt::Key_D); 0127 viewerMenu->addAction(detachAction); 0128 0129 quitAction = ac->addAction(KStandardAction::Quit, this, SLOT(close())); 0130 viewerMenu->addAction(quitAction); 0131 0132 QList<QKeySequence> shortcuts; 0133 0134 tabCloseAction = ac->addAction("closeTab", this, SLOT(tabCloseRequest())); 0135 tabCloseAction->setText(i18n("&Close Current Tab")); 0136 shortcuts = KStandardShortcut::close(); 0137 shortcuts.append(Qt::Key_Escape); 0138 ac->setDefaultShortcuts(tabCloseAction, shortcuts); 0139 0140 tabNextAction = ac->addAction("nextTab", this, SLOT(nextTab())); 0141 tabNextAction->setText(i18n("&Next Tab")); 0142 shortcuts = KStandardShortcut::tabNext(); 0143 shortcuts.append(Qt::CTRL + Qt::Key_Tab); // reenforce QTabWidget shortcut 0144 ac->setDefaultShortcuts(tabNextAction, shortcuts); 0145 0146 tabPrevAction = ac->addAction("prevTab", this, SLOT(prevTab())); 0147 tabPrevAction->setText(i18n("&Previous Tab")); 0148 shortcuts = KStandardShortcut::tabPrev(); 0149 shortcuts.append(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab); // reenforce QTabWidget shortcut 0150 ac->setDefaultShortcuts(tabPrevAction, shortcuts); 0151 0152 tabWidget.setTabsClosable(true); 0153 0154 checkModified(); 0155 0156 KConfigGroup group(krConfig, "KrViewerWindow"); 0157 int sx = group.readEntry("Window Width", -1); 0158 int sy = group.readEntry("Window Height", -1); 0159 0160 if (sx != -1 && sy != -1) 0161 resize(sx, sy); 0162 else 0163 resize(900, 700); 0164 0165 if (group.readEntry("Window Maximized", false)) { 0166 setWindowState(windowState() | Qt::WindowMaximized); 0167 } 0168 0169 // filtering out the key events 0170 menuBar()->installEventFilter(this); 0171 } 0172 0173 KrViewer::~KrViewer() 0174 { 0175 disconnect(&manager, SIGNAL(activePartChanged(KParts::Part *)), this, SLOT(createGUI(KParts::Part *))); 0176 0177 viewers.removeAll(this); 0178 0179 // close tabs before deleting tab bar - this avoids Qt bug 26115 0180 // https://bugreports.qt-project.org/browse/QTBUG-26115 0181 while (tabWidget.count()) 0182 tabCloseRequest(tabWidget.currentIndex(), true); 0183 0184 delete printAction; 0185 delete copyAction; 0186 } 0187 0188 void KrViewer::configureDeps() 0189 { 0190 PanelEditor::configureDeps(); 0191 } 0192 0193 void KrViewer::createGUI(KParts::Part *part) 0194 { 0195 KParts::MainWindow::createGUI(part); 0196 0197 updateActions(); 0198 0199 toolBar()->show(); 0200 statusBar()->show(); 0201 0202 // the KParts part may override the viewer shortcuts. We prevent it 0203 // by installing an event filter on the menuBar() and the part 0204 reservedKeys.clear(); 0205 reservedKeyActions.clear(); 0206 0207 QList<QAction *> list = viewerMenu->actions(); 0208 // also add the actions that are not in the menu... 0209 list << tabCloseAction << tabNextAction << tabPrevAction; 0210 // getting the key sequences of the viewer menu 0211 for (int w = 0; w != list.count(); w++) { 0212 QAction *act = list[w]; 0213 QList<QKeySequence> sequences = act->shortcuts(); 0214 foreach (QKeySequence keySeq, sequences) { 0215 for (int i = 0; i < keySeq.count(); ++i) { 0216 reservedKeys.push_back(keySeq[i]); 0217 reservedKeyActions.push_back(act); // the same action many times in case of multiple shortcuts 0218 } 0219 } 0220 } 0221 0222 // and "fix" the menubar 0223 viewerMenu->setTitle(i18n("&KrViewer")); 0224 QAction *act = menuBar()->addMenu(viewerMenu); 0225 act->setData(QVariant(70)); 0226 menuBar()->show(); 0227 } 0228 0229 void KrViewer::configureShortcuts() 0230 { 0231 #if KXMLGUI_VERSION >= QT_VERSION_CHECK(5, 84, 0) 0232 KShortcutsDialog::showDialog(actionCollection(), KShortcutsEditor::LetterShortcutsAllowed, this); 0233 #else 0234 KShortcutsDialog::configure(actionCollection(), KShortcutsEditor::LetterShortcutsAllowed, this); 0235 #endif 0236 } 0237 0238 bool KrViewer::eventFilter(QObject * /* watched */, QEvent *e) 0239 { 0240 // TODO: after porting to Qt5/KF5 we never catch *ANY* KeyPress or ShortcutOverride events here anymore. 0241 // Should look into if there is any way to fix it. Currently if a KPart has same shortcut as KrViewer then 0242 // it causes a conflict, messagebox shown to user and no action triggered. 0243 if (e->type() == QEvent::ShortcutOverride) { 0244 auto *ke = dynamic_cast<QKeyEvent *>(e); 0245 if (reservedKeys.contains(ke->key())) { 0246 ke->accept(); 0247 0248 QAction *act = reservedKeyActions[reservedKeys.indexOf(ke->key())]; 0249 if (act != nullptr) { 0250 // don't activate the close functions immediately! 0251 // it can cause crash 0252 if (act == tabCloseAction || act == quitAction) { 0253 QTimer::singleShot(0, act, &QAction::trigger); 0254 } else { 0255 act->activate(QAction::Trigger); 0256 } 0257 } 0258 return true; 0259 } 0260 } else if (e->type() == QEvent::KeyPress) { 0261 auto *ke = dynamic_cast<QKeyEvent *>(e); 0262 if (reservedKeys.contains(ke->key())) { 0263 ke->accept(); 0264 return true; 0265 } 0266 } 0267 return false; 0268 } 0269 0270 KrViewer *KrViewer::getViewer(bool new_window) 0271 { 0272 if (!new_window) { 0273 if (viewers.isEmpty()) { 0274 viewers.prepend(new KrViewer()); // add to first (active) 0275 } else { 0276 if (viewers.first()->isMinimized()) { // minimized? -> show it again 0277 viewers.first()->setWindowState((viewers.first()->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); 0278 viewers.first()->show(); 0279 } 0280 viewers.first()->raise(); 0281 viewers.first()->activateWindow(); 0282 } 0283 return viewers.first(); 0284 } else { 0285 auto *newViewer = new KrViewer(); 0286 viewers.prepend(newViewer); 0287 return newViewer; 0288 } 0289 } 0290 0291 void KrViewer::view(QUrl url, QWidget *parent) 0292 { 0293 KConfigGroup group(krConfig, "General"); 0294 bool defaultWindow = group.readEntry("View In Separate Window", _ViewInSeparateWindow); 0295 0296 view(std::move(url), Default, defaultWindow, parent); 0297 } 0298 0299 void KrViewer::view(QUrl url, Mode mode, bool new_window, QWidget *parent) 0300 { 0301 KrViewer *viewer = getViewer(new_window); 0302 viewer->viewInternal(std::move(url), mode, parent); 0303 viewer->show(); 0304 } 0305 0306 void KrViewer::edit(QUrl url, QWidget *parent) 0307 { 0308 edit(std::move(url), Text, -1, parent); 0309 } 0310 0311 void KrViewer::edit(const QUrl &url, Mode mode, int new_window, QWidget *parent) 0312 { 0313 KConfigGroup group(krConfig, "General"); 0314 QString editor = group.readEntry("Editor", _Editor); 0315 0316 if (new_window == -1) 0317 new_window = group.readEntry("View In Separate Window", _ViewInSeparateWindow); 0318 0319 if (editor != "internal editor" && !editor.isEmpty()) { 0320 KProcess proc; 0321 QStringList cmdArgs = KShell::splitArgs(editor, KShell::TildeExpand); 0322 if (cmdArgs.isEmpty()) { 0323 KMessageBox::error(krMainWindow, i18nc("Arg is a string containing the bad quoting.", "Bad quoting in editor command:\n%1", editor)); 0324 return; 0325 } 0326 // if the file is local, pass a normal path and not a url. this solves 0327 // the problem for editors that aren't url-aware 0328 proc << cmdArgs << url.toDisplayString(QUrl::PreferLocalFile); 0329 if (!proc.startDetached()) 0330 KMessageBox::error(krMainWindow, i18n("Can not open \"%1\"", editor)); 0331 return; 0332 } 0333 0334 KrViewer *viewer = getViewer(new_window); 0335 viewer->editInternal(url, mode, parent); 0336 viewer->show(); 0337 } 0338 0339 void KrViewer::addTab(PanelViewerBase *pvb) 0340 { 0341 int tabIndex = tabWidget.addTab(pvb, makeTabIcon(pvb), makeTabText(pvb)); 0342 tabWidget.setCurrentIndex(tabIndex); 0343 tabWidget.setTabToolTip(tabIndex, makeTabToolTip(pvb)); 0344 0345 updateActions(); 0346 0347 // now we can offer the option to detach tabs (we have more than one) 0348 if (tabWidget.count() > 1) 0349 detachAction->setEnabled(true); 0350 tabWidget.adjustViewerTabBarVisibility(); 0351 0352 tabWidget.show(); 0353 0354 connect(pvb, &PanelViewerBase::openUrlFinished, this, &KrViewer::openUrlFinished); 0355 0356 connect(pvb, &PanelViewerBase::urlChanged, this, &KrViewer::tabURLChanged); 0357 } 0358 0359 void KrViewer::tabURLChanged(PanelViewerBase *pvb, const QUrl &url) 0360 { 0361 Q_UNUSED(url) 0362 refreshTab(pvb); 0363 } 0364 0365 void KrViewer::openUrlFinished(PanelViewerBase *pvb, bool success) 0366 { 0367 if (success) { 0368 KParts::ReadOnlyPart *part = pvb->part(); 0369 if (part) { 0370 if (!isPartAdded(part)) 0371 addPart(part); 0372 if (tabWidget.currentWidget() == pvb) { 0373 manager.setActivePart(part); 0374 if (part->widget()) 0375 part->widget()->setFocus(); 0376 } 0377 } 0378 } else { 0379 tabCloseRequest(tabWidget.currentIndex(), false); 0380 } 0381 } 0382 0383 void KrViewer::tabChanged(int index) 0384 { 0385 QWidget *w = tabWidget.widget(index); 0386 if (!w) 0387 return; 0388 KParts::ReadOnlyPart *part = dynamic_cast<PanelViewerBase *>(w)->part(); 0389 if (part && isPartAdded(part)) { 0390 manager.setActivePart(part); 0391 if (part->widget()) 0392 part->widget()->setFocus(); 0393 } else 0394 manager.setActivePart(nullptr); 0395 0396 // set this viewer to be the main viewer 0397 if (viewers.removeAll(this)) 0398 viewers.prepend(this); // move to first 0399 } 0400 0401 void KrViewer::tabCloseRequest(int index, bool force) 0402 { 0403 // important to save as returnFocusTo will be cleared at removePart 0404 QWidget *returnFocusToThisWidget = returnFocusTo; 0405 0406 auto *pvb = dynamic_cast<PanelViewerBase *>(tabWidget.widget(index)); 0407 if (!pvb) 0408 return; 0409 0410 if (!force && !pvb->queryClose()) 0411 return; 0412 0413 if (pvb->part() && isPartAdded(pvb->part())) 0414 removePart(pvb->part()); 0415 0416 disconnect(pvb, nullptr, this, nullptr); 0417 0418 pvb->closeUrl(); 0419 0420 tabWidget.removeTab(index); 0421 0422 delete pvb; 0423 pvb = nullptr; 0424 0425 if (tabWidget.count() <= 0) { 0426 if (returnFocusToThisWidget) { 0427 returnFocusToThisWidget->raise(); 0428 returnFocusToThisWidget->activateWindow(); 0429 } else { 0430 krMainWindow->raise(); 0431 krMainWindow->activateWindow(); 0432 } 0433 0434 QTimer::singleShot(0, this, &KrViewer::close); 0435 } else if (tabWidget.count() == 1) { 0436 // no point in detaching only one tab.. 0437 detachAction->setEnabled(false); 0438 tabWidget.adjustViewerTabBarVisibility(); 0439 } 0440 } 0441 0442 void KrViewer::tabCloseRequest() 0443 { 0444 tabCloseRequest(tabWidget.currentIndex()); 0445 } 0446 0447 bool KrViewer::queryClose() 0448 { 0449 KConfigGroup group(krConfig, "KrViewerWindow"); 0450 0451 group.writeEntry("Window Width", sizeX); 0452 group.writeEntry("Window Height", sizeY); 0453 group.writeEntry("Window Maximized", isMaximized()); 0454 0455 for (int i = 0; i != tabWidget.count(); i++) { 0456 auto *pvb = dynamic_cast<PanelViewerBase *>(tabWidget.widget(i)); 0457 if (!pvb) 0458 continue; 0459 0460 tabWidget.setCurrentIndex(i); 0461 0462 if (!pvb->queryClose()) 0463 return false; 0464 } 0465 return true; 0466 } 0467 0468 void KrViewer::viewGeneric() 0469 { 0470 auto *pvb = dynamic_cast<PanelViewerBase *>(tabWidget.currentWidget()); 0471 if (pvb) 0472 viewInternal(pvb->url(), Generic); 0473 } 0474 0475 void KrViewer::viewText() 0476 { 0477 auto *pvb = dynamic_cast<PanelViewerBase *>(tabWidget.currentWidget()); 0478 if (pvb) 0479 viewInternal(pvb->url(), Text); 0480 } 0481 0482 void KrViewer::viewLister() 0483 { 0484 auto *pvb = dynamic_cast<PanelViewerBase *>(tabWidget.currentWidget()); 0485 if (pvb) 0486 viewInternal(pvb->url(), Lister); 0487 } 0488 0489 void KrViewer::viewHex() 0490 { 0491 auto *pvb = dynamic_cast<PanelViewerBase *>(tabWidget.currentWidget()); 0492 if (pvb) 0493 viewInternal(pvb->url(), Hex); 0494 } 0495 0496 void KrViewer::editText() 0497 { 0498 auto *pvb = dynamic_cast<PanelViewerBase *>(tabWidget.currentWidget()); 0499 if (pvb) 0500 editInternal(pvb->url(), Text); 0501 } 0502 0503 void KrViewer::checkModified() 0504 { 0505 QTimer::singleShot(CHECK_MODFIED_INTERVAL, this, &KrViewer::checkModified); 0506 0507 auto *pvb = dynamic_cast<PanelViewerBase *>(tabWidget.currentWidget()); 0508 if (pvb) 0509 refreshTab(pvb); 0510 } 0511 0512 void KrViewer::refreshTab(PanelViewerBase *pvb) 0513 { 0514 int ndx = tabWidget.indexOf(pvb); 0515 tabWidget.setTabText(ndx, makeTabText(pvb)); 0516 tabWidget.setTabIcon(ndx, makeTabIcon(pvb)); 0517 tabWidget.setTabToolTip(ndx, makeTabToolTip(pvb)); 0518 } 0519 0520 void KrViewer::nextTab() 0521 { 0522 int index = (tabWidget.currentIndex() + 1) % tabWidget.count(); 0523 tabWidget.setCurrentIndex(index); 0524 } 0525 0526 void KrViewer::prevTab() 0527 { 0528 int index = (tabWidget.currentIndex() - 1) % tabWidget.count(); 0529 while (index < 0) 0530 index += tabWidget.count(); 0531 tabWidget.setCurrentIndex(index); 0532 } 0533 0534 void KrViewer::detachTab() 0535 { 0536 auto *pvb = dynamic_cast<PanelViewerBase *>(tabWidget.currentWidget()); 0537 if (!pvb) 0538 return; 0539 0540 KrViewer *viewer = getViewer(true); 0541 0542 bool wasPartAdded = false; 0543 KParts::ReadOnlyPart *part = pvb->part(); 0544 0545 if (part && isPartAdded(part)) { 0546 wasPartAdded = true; 0547 removePart(part); 0548 } 0549 0550 disconnect(pvb, nullptr, this, nullptr); 0551 0552 tabWidget.removeTab(tabWidget.indexOf(pvb)); 0553 0554 if (tabWidget.count() == 1) { 0555 // no point in detaching only one tab.. 0556 detachAction->setEnabled(false); 0557 tabWidget.adjustViewerTabBarVisibility(); 0558 } 0559 0560 pvb->setParent(&viewer->tabWidget); 0561 pvb->move(QPoint(0, 0)); 0562 0563 viewer->addTab(pvb); 0564 0565 if (wasPartAdded) { 0566 viewer->addPart(part); 0567 if (part->widget()) 0568 part->widget()->setFocus(); 0569 } 0570 0571 viewer->show(); 0572 } 0573 0574 void KrViewer::changeEvent(QEvent *e) 0575 { 0576 if (e->type() == QEvent::ActivationChange && isActiveWindow()) 0577 if (viewers.removeAll(this)) 0578 viewers.prepend(this); // move to first 0579 } 0580 0581 void KrViewer::print() 0582 { 0583 auto *pvb = dynamic_cast<PanelViewerBase *>(tabWidget.currentWidget()); 0584 if (!pvb || !pvb->part() || !isPartAdded(pvb->part())) 0585 return; 0586 0587 KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject(pvb->part()); 0588 if (ext && ext->isActionEnabled("print")) 0589 Invoker(ext, SLOT(print())).invoke(); 0590 } 0591 0592 void KrViewer::copy() 0593 { 0594 auto *pvb = dynamic_cast<PanelViewerBase *>(tabWidget.currentWidget()); 0595 if (!pvb || !pvb->part() || !isPartAdded(pvb->part())) 0596 return; 0597 0598 KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject(pvb->part()); 0599 if (ext && ext->isActionEnabled("copy")) 0600 Invoker(ext, SLOT(copy())).invoke(); 0601 } 0602 0603 void KrViewer::updateActions() 0604 { 0605 QList<QAction *> actList = toolBar()->actions(); 0606 bool hasPrint = false, hasCopy = false; 0607 foreach (QAction *a, actList) { 0608 if (a->text() == printAction->text()) 0609 hasPrint = true; 0610 if (a->text() == copyAction->text()) 0611 hasCopy = true; 0612 } 0613 if (!hasPrint) 0614 toolBar()->addAction(printAction->icon(), printAction->text(), this, SLOT(print())); 0615 if (!hasCopy) 0616 toolBar()->addAction(copyAction->icon(), copyAction->text(), this, SLOT(copy())); 0617 } 0618 0619 bool KrViewer::isPartAdded(KParts::Part *part) 0620 { 0621 return manager.parts().contains(part); 0622 } 0623 0624 void KrViewer::resizeEvent(QResizeEvent *e) 0625 { 0626 if (!isMaximized()) { 0627 sizeX = e->size().width(); 0628 sizeY = e->size().height(); 0629 } 0630 0631 KParts::MainWindow::resizeEvent(e); 0632 } 0633 0634 QString KrViewer::makeTabText(PanelViewerBase *pvb) 0635 { 0636 QString fileName = pvb->url().fileName(); 0637 if (pvb->isModified()) 0638 fileName.prepend("*"); 0639 0640 return pvb->isEditor() ? i18nc("filename (filestate)", "%1 (Editing)", fileName) : i18nc("filename (filestate)", "%1 (Viewing)", fileName); 0641 } 0642 0643 QString KrViewer::makeTabToolTip(PanelViewerBase *pvb) 0644 { 0645 QString url = pvb->url().toDisplayString(QUrl::PreferLocalFile); 0646 return pvb->isEditor() ? i18nc("filestate: filename", "Editing: %1", url) : i18nc("filestate: filename", "Viewing: %1", url); 0647 } 0648 0649 QIcon KrViewer::makeTabIcon(PanelViewerBase *pvb) 0650 { 0651 QString iconName; 0652 if (pvb->isModified()) 0653 iconName = MODIFIED_ICON; 0654 else if (pvb->isEditor()) 0655 iconName = EDIT_ICON; 0656 else 0657 iconName = VIEW_ICON; 0658 0659 return Icon(iconName); 0660 } 0661 0662 void KrViewer::addPart(KParts::ReadOnlyPart *part) 0663 { 0664 Q_ASSERT(part); 0665 Q_ASSERT(!isPartAdded(part)); 0666 0667 if (isPartAdded(part)) { 0668 qDebug() << "part already added:" << part; 0669 return; 0670 } 0671 0672 connect(part, SIGNAL(setStatusBarText(QString)), this, SLOT(slotSetStatusBarText(QString))); 0673 // filtering out the key events 0674 part->installEventFilter(this); 0675 0676 manager.addPart(part, false); // don't automatically set active part 0677 } 0678 0679 void KrViewer::removePart(KParts::ReadOnlyPart *part) 0680 { 0681 Q_ASSERT(part); 0682 Q_ASSERT(isPartAdded(part)); 0683 0684 if (isPartAdded(part)) { 0685 disconnect(part, nullptr, this, nullptr); 0686 part->removeEventFilter(this); 0687 manager.removePart(part); 0688 } else 0689 qDebug() << "part hasn't been added:" << part; 0690 } 0691 0692 void KrViewer::viewInternal(QUrl url, Mode mode, QWidget *parent) 0693 { 0694 returnFocusTo = parent; 0695 0696 PanelViewerBase *viewWidget = new PanelViewer(&tabWidget, mode); 0697 0698 addTab(viewWidget); 0699 viewWidget->openUrl(std::move(url)); 0700 } 0701 0702 void KrViewer::editInternal(QUrl url, Mode mode, QWidget *parent) 0703 { 0704 returnFocusTo = parent; 0705 0706 PanelViewerBase *editWidget = new PanelEditor(&tabWidget, mode); 0707 0708 addTab(editWidget); 0709 editWidget->openUrl(std::move(url)); 0710 }