mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 10:22:50 +00:00
kman: import
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
681126269e
commit
371f75b17b
8 changed files with 676 additions and 0 deletions
|
@ -21,3 +21,4 @@ macro_optional_add_subdirectory (kcachegrind)
|
|||
# macro_optional_add_subdirectory (kdepimlibs)
|
||||
# macro_optional_add_subdirectory (kdepim-runtime)
|
||||
# macro_optional_add_subdirectory (kdepim)
|
||||
macro_optional_add_subdirectory (kman)
|
||||
|
|
20
kman/CMakeLists.txt
Normal file
20
kman/CMakeLists.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
project(kman)
|
||||
|
||||
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
find_package(KDE4 4.19.0 REQUIRED)
|
||||
include(KDE4Defaults)
|
||||
include_directories(${KDE4_INCLUDES})
|
||||
add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
|
||||
endif()
|
||||
|
||||
set(kman_sources
|
||||
main.cpp
|
||||
kmanmainwindow.cpp
|
||||
)
|
||||
|
||||
add_executable(kman ${kman_sources})
|
||||
target_link_libraries(kman ${KDE4_KDEUI_LIBS} ${KDE4_KFILE_LIBS})
|
||||
|
||||
install(TARGETS kman DESTINATION ${KDE4_BIN_INSTALL_DIR})
|
||||
install(FILES kmanui.rc DESTINATION ${KDE4_DATA_INSTALL_DIR}/kman)
|
||||
install(PROGRAMS kman.desktop DESTINATION ${KDE4_XDG_APPS_INSTALL_DIR})
|
10
kman/kman.desktop
Normal file
10
kman/kman.desktop
Normal file
|
@ -0,0 +1,10 @@
|
|||
[Desktop Entry]
|
||||
Icon=help-browser
|
||||
Name=KMan
|
||||
GenericName=KMan
|
||||
Comment=Simple manual page reader for KDE
|
||||
Exec=kman --icon '%i' --caption '%c' %U
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Qt;KDE;System;
|
||||
MimeType=text/troff;
|
87
kman/kman.ui
Normal file
87
kman/kman.ui
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>KManWindow</class>
|
||||
<widget class="QMainWindow" name="KManWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>545</width>
|
||||
<height>508</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>KManPageApp</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset theme="help-browser">
|
||||
<normaloff/>
|
||||
</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLineEdit" name="searchEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Search in names..</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<widget class="QTextBrowser" name="manView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" stdset="0">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QListWidget" name="listWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
402
kman/kmanmainwindow.cpp
Normal file
402
kman/kmanmainwindow.cpp
Normal file
|
@ -0,0 +1,402 @@
|
|||
/* This file is part of KMan
|
||||
Copyright (C) 2018 Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
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 <KAction>
|
||||
#include <KActionCollection>
|
||||
#include <KLocale>
|
||||
#include <KIcon>
|
||||
#include <KDebug>
|
||||
#include <KStatusBar>
|
||||
#include <KFileDialog>
|
||||
#include <KFilterDev>
|
||||
#include <QThread>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QFileInfo>
|
||||
#include <QDirIterator>
|
||||
#include <QStandardPaths>
|
||||
#include <QProcess>
|
||||
#include <QMessageBox>
|
||||
#include <QInputDialog>
|
||||
|
||||
#include "kmanmainwindow.h"
|
||||
#include "ui_kman.h"
|
||||
|
||||
static QMap<QString,QString> s_mans;
|
||||
static QFileSystemWatcher s_watcher;
|
||||
|
||||
class KManLister : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KManLister(QObject *parent = Q_NULLPTR);
|
||||
|
||||
QList<QByteArray> m_paths;
|
||||
bool m_interrupt;
|
||||
|
||||
public Q_SLOTS:
|
||||
void slotScan(QString path);
|
||||
|
||||
Q_SIGNALS:
|
||||
void resultRead(const QString path, const QString fancy);
|
||||
|
||||
protected:
|
||||
// reimplementation
|
||||
virtual void run();
|
||||
};
|
||||
|
||||
KManLister::KManLister(QObject *parent)
|
||||
: QThread(parent),
|
||||
m_interrupt(false) {
|
||||
QByteArray manpath = qgetenv("MANPATH");
|
||||
if (manpath.isEmpty()) {
|
||||
manpath = "/usr/local/share/man:/usr/share/man:/usr/local/man:/usr/man";
|
||||
}
|
||||
foreach (const QByteArray &path, manpath.split(':')) {
|
||||
QFileInfo pathinfo = QFileInfo(path);
|
||||
if (!pathinfo.exists()) {
|
||||
continue;
|
||||
}
|
||||
m_paths << path;
|
||||
kDebug() << "watching" << path;
|
||||
s_watcher.addPath(path);
|
||||
}
|
||||
|
||||
connect(&s_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(slotScan(QString)));
|
||||
}
|
||||
|
||||
void KManLister::slotScan(QString path) {
|
||||
kDebug() << "rescanning" << path;
|
||||
if (isRunning()) {
|
||||
m_interrupt = true;
|
||||
wait();
|
||||
}
|
||||
start();
|
||||
}
|
||||
|
||||
void KManLister::run() {
|
||||
setPriority(QThread::LowPriority);
|
||||
|
||||
s_mans.clear();
|
||||
m_interrupt = false;
|
||||
|
||||
foreach (const QByteArray &path, m_paths) {
|
||||
kDebug() << "scanning" << path;
|
||||
|
||||
QDirIterator iterator(path, QDirIterator::Subdirectories);
|
||||
while (iterator.hasNext()) {
|
||||
if (m_interrupt) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString manpage = QDir::cleanPath(iterator.next());
|
||||
const QFileInfo info = iterator.fileInfo();
|
||||
if (info.isDir()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const QString section = info.path().remove(0, path.size() + 1);
|
||||
QString fancypage = section + "/" + info.fileName();
|
||||
const QString suffix = info.completeSuffix();
|
||||
if (!suffix.isEmpty()) {
|
||||
fancypage = fancypage.left(fancypage.size() - suffix.size() - 1);
|
||||
}
|
||||
|
||||
s_mans.insert(manpage, fancypage);
|
||||
emit resultRead(path, fancypage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KManMainWindow::KManMainWindow(QWidget *parent, Qt::WindowFlags flags)
|
||||
: KXmlGuiWindow(parent, flags), m_kmanui(new Ui_KManWindow), m_lister(new KManLister(this))
|
||||
{
|
||||
m_kmanui->setupUi(this);
|
||||
|
||||
m_actionopen = actionCollection()->addAction("file_open", this, SLOT(slotOpenAction()));
|
||||
m_actionopen->setText(i18n("Open"));
|
||||
m_actionopen->setIcon(KIcon("document-open"));
|
||||
m_actionopen->setShortcut(KStandardShortcut::open());
|
||||
m_actionopen->setWhatsThis(i18n("Open manual page."));
|
||||
|
||||
m_actionquit = actionCollection()->addAction("file_quit", this, SLOT(slotQuitAction()));
|
||||
m_actionquit->setText(i18n("Quit"));
|
||||
m_actionquit->setIcon(KIcon("application-exit"));
|
||||
m_actionquit->setShortcut(KStandardShortcut::quit());
|
||||
m_actionquit->setWhatsThis(i18n("Close the application."));
|
||||
|
||||
m_actionnext = actionCollection()->addAction("view_next", this, SLOT(slotNextAction()));
|
||||
m_actionnext->setText(i18n("Next"));
|
||||
m_actionnext->setIcon(KIcon("go-next"));
|
||||
m_actionnext->setShortcut(KStandardShortcut::forward());
|
||||
m_actionnext->setWhatsThis(i18n("Switch to the next manual page in the list."));
|
||||
|
||||
m_actionprevious = actionCollection()->addAction("view_previous", this, SLOT(slotPreviousAction()));
|
||||
m_actionprevious->setText(i18n("Previous"));
|
||||
m_actionprevious->setIcon(KIcon("go-previous"));
|
||||
m_actionprevious->setShortcut(KStandardShortcut::back());
|
||||
m_actionprevious->setWhatsThis(i18n("Switch to the previous manual page in the list."));
|
||||
|
||||
m_actionfind = actionCollection()->addAction("find_find", this, SLOT(slotFindAction()));
|
||||
m_actionfind->setText(i18n("Find"));
|
||||
m_actionfind->setIcon(KIcon("edit-find"));
|
||||
m_actionfind->setShortcut(KStandardShortcut::find());
|
||||
m_actionfind->setWhatsThis(i18n("Find in the manual page."));
|
||||
|
||||
m_actionfindnext = actionCollection()->addAction("find_next", this, SLOT(slotFindNextAction()));
|
||||
m_actionfindnext->setText(i18n("Find Next"));
|
||||
m_actionfindnext->setIcon(KIcon("go-next"));
|
||||
m_actionfindnext->setShortcut(KStandardShortcut::findNext());
|
||||
m_actionfindnext->setWhatsThis(i18n("Find next match in the manual page."));
|
||||
|
||||
m_actionfindprevious = actionCollection()->addAction("find_previous", this, SLOT(slotFindPreviousAction()));
|
||||
m_actionfindprevious->setText(i18n("Find Previous"));
|
||||
m_actionfindprevious->setIcon(KIcon("go-previous"));
|
||||
m_actionfindprevious->setShortcut(KStandardShortcut::findPrev());
|
||||
m_actionfindprevious->setWhatsThis(i18n("Find previous match in the manual page."));
|
||||
|
||||
setupGUI();
|
||||
setAutoSaveSettings();
|
||||
|
||||
setWindowIcon(KIcon("help-browser"));
|
||||
|
||||
connect(m_kmanui->searchEdit, SIGNAL(textChanged(const QString &)),
|
||||
this, SLOT(slotSearchChanged(const QString &)));
|
||||
connect(m_kmanui->listWidget, SIGNAL(currentTextChanged(const QString &)),
|
||||
this, SLOT(slotListChanged(const QString &)));
|
||||
|
||||
connect(m_lister, SIGNAL(started()), this, SLOT(slotBusyStart()));
|
||||
connect(m_lister, SIGNAL(resultRead(const QString, const QString)),
|
||||
this, SLOT(slotListResult(const QString, const QString)));
|
||||
connect(m_lister, SIGNAL(finished()), this, SLOT(slotBusyFinish()));
|
||||
|
||||
listManPages();
|
||||
}
|
||||
|
||||
KManMainWindow::~KManMainWindow()
|
||||
{
|
||||
saveAutoSaveSettings();
|
||||
m_lister->terminate();
|
||||
delete m_lister;
|
||||
delete m_kmanui;
|
||||
}
|
||||
|
||||
void KManMainWindow::changePath(const QString path) {
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_path = path;
|
||||
|
||||
const QString content = manContent(path);
|
||||
m_kmanui->manView->setHtml(content);
|
||||
|
||||
statusBar()->showMessage(path);
|
||||
|
||||
// TODO: m_kmanui->menuFind->setEnabled(!content.isEmpty());
|
||||
|
||||
const QString fancypage = s_mans.value(path);
|
||||
if (!fancypage.isEmpty()) {
|
||||
QList<QListWidgetItem*> items = m_kmanui->listWidget->findItems(fancypage, Qt::MatchExactly);
|
||||
if (items.count() > 0) {
|
||||
m_kmanui->listWidget->setCurrentItem(items.first());
|
||||
} else {
|
||||
QMessageBox::warning(this, windowTitle(), i18n("not in list %1", fancypage));
|
||||
}
|
||||
} else {
|
||||
kDebug() << "not in cache" << path;
|
||||
}
|
||||
|
||||
m_actionnext->setEnabled(false);
|
||||
m_actionprevious->setEnabled(false);
|
||||
const int position = m_kmanui->listWidget->currentRow();
|
||||
if ((position + 1) < m_kmanui->listWidget->count()) {
|
||||
m_actionnext->setEnabled(true);
|
||||
}
|
||||
if (position >= 1) {
|
||||
m_actionprevious->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void KManMainWindow::slotOpenAction() {
|
||||
const QString path = KFileDialog::getOpenFileName(KUrl(), QLatin1String("text/troff"), this, i18n("Manual page path"));
|
||||
if (!path.isEmpty()) {
|
||||
changePath(path);
|
||||
}
|
||||
}
|
||||
|
||||
void KManMainWindow::slotQuitAction() {
|
||||
qApp->quit();
|
||||
}
|
||||
|
||||
void KManMainWindow::slotNextAction() {
|
||||
const int position = m_kmanui->listWidget->currentRow();
|
||||
if ((position + 1) < m_kmanui->listWidget->count()) {
|
||||
m_kmanui->listWidget->setCurrentRow(position + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void KManMainWindow::slotPreviousAction() {
|
||||
const int position = m_kmanui->listWidget->currentRow();
|
||||
if (position >= 1) {
|
||||
m_kmanui->listWidget->setCurrentRow(position - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void KManMainWindow::slotFindAction() {
|
||||
const QString text = QInputDialog::getText(this, windowTitle(), i18n("Find:"));
|
||||
if (text.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
m_search = text;
|
||||
m_actionfindnext->setEnabled(true);
|
||||
m_actionfindprevious->setEnabled(true);
|
||||
|
||||
if (!m_kmanui->manView->find(text)) {
|
||||
QMessageBox::information(this, windowTitle(), i18n("No match was found"));
|
||||
}
|
||||
}
|
||||
|
||||
void KManMainWindow::slotFindNextAction() {
|
||||
if (m_search.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_kmanui->manView->find(m_search)) {
|
||||
QMessageBox::information(this, windowTitle(), i18n("No match was found"));
|
||||
}
|
||||
}
|
||||
|
||||
void KManMainWindow::slotFindPreviousAction() {
|
||||
if (m_search.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_kmanui->manView->find(m_search, QTextDocument::FindBackward)) {
|
||||
QMessageBox::information(this, windowTitle(), i18n("No match was found"));
|
||||
}
|
||||
}
|
||||
|
||||
void KManMainWindow::slotSearchChanged(const QString &text) {
|
||||
m_kmanui->listWidget->clear();
|
||||
foreach (const QString &man, s_mans.values()) {
|
||||
if (text.isEmpty() || man.indexOf(text) >= 0) {
|
||||
QListWidgetItem* manitem = new QListWidgetItem(KIcon("application-x-troff-man"), man, m_kmanui->listWidget);
|
||||
m_kmanui->listWidget->addItem(manitem);
|
||||
}
|
||||
}
|
||||
m_kmanui->listWidget->sortItems();
|
||||
}
|
||||
|
||||
void KManMainWindow::slotListChanged(const QString &text) {
|
||||
const QString manpath = s_mans.key(text);
|
||||
if (!manpath.isEmpty()) {
|
||||
changePath(manpath);
|
||||
} else {
|
||||
kDebug() << "not in cache" << text;
|
||||
}
|
||||
}
|
||||
|
||||
void KManMainWindow::slotListResult(const QString path, const QString fancy) {
|
||||
QListWidgetItem* manitem = new QListWidgetItem(KIcon("application-x-troff-man"), fancy, m_kmanui->listWidget);
|
||||
m_kmanui->listWidget->addItem(manitem);
|
||||
}
|
||||
|
||||
void KManMainWindow::slotBusyStart() {
|
||||
// TODO: m_kmanui->menuFile->setEnabled(false);
|
||||
// TODO: m_kmanui->menuAction->setEnabled(false);
|
||||
// TODO: m_kmanui->menuFind->setEnabled(false);
|
||||
m_kmanui->searchEdit->setEnabled(false);
|
||||
m_kmanui->listWidget->setEnabled(false);
|
||||
m_kmanui->progressBar->setRange(0, 0);
|
||||
m_kmanui->progressBar->setVisible(true);
|
||||
}
|
||||
|
||||
void KManMainWindow::slotBusyFinish() {
|
||||
m_kmanui->listWidget->sortItems();
|
||||
|
||||
|
||||
m_kmanui->progressBar->setRange(0, 1);
|
||||
m_kmanui->progressBar->setVisible(false);
|
||||
m_kmanui->listWidget->setEnabled(true);
|
||||
m_kmanui->searchEdit->setEnabled(true);
|
||||
// TODO: m_kmanui->menuAction->setEnabled(true);
|
||||
// TODO: m_kmanui->menuFile->setEnabled(true);
|
||||
}
|
||||
|
||||
void KManMainWindow::listManPages() {
|
||||
if (s_mans.isEmpty()) {
|
||||
m_lister->start();
|
||||
}
|
||||
}
|
||||
|
||||
QString KManMainWindow::manContent(const QString path) {
|
||||
QString result;
|
||||
|
||||
if (QStandardPaths::findExecutable("groff").isEmpty()) {
|
||||
QMessageBox::warning(this, windowTitle(), i18n("groff is not installed"));
|
||||
return result;
|
||||
}
|
||||
|
||||
QFile pathfile(path);
|
||||
if (pathfile.size() > 100000) {
|
||||
QMessageBox::warning(this, windowTitle(), i18n("manual page has size greatar than 10Mb"));
|
||||
return result;
|
||||
}
|
||||
|
||||
QByteArray content;
|
||||
if (path.endsWith(".gz") || path.endsWith(".bz2") || path.endsWith(".xz")) {
|
||||
QIODevice *archivedevice = KFilterDev::deviceForFile(path);
|
||||
if (archivedevice && archivedevice->open(QFile::ReadOnly)) {
|
||||
content = archivedevice->readAll();
|
||||
}
|
||||
archivedevice->deleteLater();
|
||||
} else {
|
||||
if (pathfile.open(QFile::ReadOnly)) {
|
||||
content = pathfile.readAll();
|
||||
}
|
||||
pathfile.close();
|
||||
}
|
||||
|
||||
if (content.isEmpty()) {
|
||||
QMessageBox::warning(this, windowTitle(), i18n("could not read %1", path));
|
||||
return result;
|
||||
}
|
||||
|
||||
slotBusyStart();
|
||||
|
||||
QProcess groff;
|
||||
groff.setWorkingDirectory(QDir::tempPath());
|
||||
groff.start("groff", QStringList() << "-mandoc" << "-c" << "-Thtml");
|
||||
groff.waitForStarted();
|
||||
groff.write(content);
|
||||
groff.closeWriteChannel();
|
||||
while (groff.state() == QProcess::Running) {
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
if (groff.exitCode() != 0 ) {
|
||||
QMessageBox::warning(this, windowTitle(), groff.readAllStandardError());
|
||||
} else {
|
||||
result = groff.readAll();
|
||||
}
|
||||
|
||||
slotBusyFinish();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#include "kmanmainwindow.moc"
|
76
kman/kmanmainwindow.h
Normal file
76
kman/kmanmainwindow.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* This file is part of KMan
|
||||
Copyright (C) 2018 Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef KMANWINDOW_H
|
||||
#define KMANWINDOW_H
|
||||
|
||||
#include <KXmlGuiWindow>
|
||||
#include <KAction>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class Ui_KManWindow;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class KManLister;
|
||||
|
||||
class KManMainWindow: public KXmlGuiWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KManMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0);
|
||||
~KManMainWindow();
|
||||
|
||||
void changePath(const QString path);
|
||||
|
||||
public slots:
|
||||
void slotOpenAction();
|
||||
void slotQuitAction();
|
||||
void slotNextAction();
|
||||
void slotPreviousAction();
|
||||
void slotFindAction();
|
||||
void slotFindNextAction();
|
||||
void slotFindPreviousAction();
|
||||
void slotSearchChanged(const QString &text);
|
||||
void slotListChanged(const QString &text);
|
||||
|
||||
private slots:
|
||||
void slotListResult(const QString path, const QString fancy);
|
||||
void slotBusyStart();
|
||||
void slotBusyFinish();
|
||||
|
||||
private:
|
||||
void listManPages();
|
||||
QString manContent(const QString path);
|
||||
|
||||
private:
|
||||
Ui_KManWindow *m_kmanui;
|
||||
|
||||
KAction *m_actionopen;
|
||||
KAction *m_actionquit;
|
||||
KAction *m_actionnext;
|
||||
KAction *m_actionprevious;
|
||||
KAction *m_actionfind;
|
||||
KAction *m_actionfindnext;
|
||||
KAction *m_actionfindprevious;
|
||||
|
||||
QString m_path;
|
||||
QString m_search;
|
||||
KManLister *m_lister;
|
||||
};
|
||||
|
||||
#endif // KMANWINDOW_H
|
25
kman/kmanui.rc
Normal file
25
kman/kmanui.rc
Normal file
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
|
||||
<kpartgui name="kman" version="3" >
|
||||
<MenuBar>
|
||||
<Menu name="file"><text>&File</text>
|
||||
<Action name="file_open"/>
|
||||
<Separator/>
|
||||
<Action name="file_quit"/>
|
||||
</Menu>
|
||||
|
||||
<Menu name="view"><text>&View</text>
|
||||
<Action name="view_next"/>
|
||||
<Action name="view_previous"/>
|
||||
</Menu>
|
||||
|
||||
<Menu name="find"><text>&Find</text>
|
||||
<Action name="find_find"/>
|
||||
<Separator/>
|
||||
<Action name="find_next"/>
|
||||
<Action name="find_previous"/>
|
||||
</Menu>
|
||||
</MenuBar>
|
||||
|
||||
<ToolBar name="mainToolBar" disable="1"><text>Main Toolbar</text>
|
||||
</ToolBar>
|
||||
</kpartgui>
|
55
kman/main.cpp
Normal file
55
kman/main.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* This file is part of KMan
|
||||
Copyright (C) 2018 Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
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 <KAboutData>
|
||||
#include <KCmdLineArgs>
|
||||
#include <KUniqueApplication>
|
||||
#include <KUrl>
|
||||
#include "kmanmainwindow.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
KAboutData aboutData("kman", 0, ki18n("KMan"),
|
||||
"1.0.0", ki18n("Simple manual page reader for KDE."),
|
||||
KAboutData::License_GPL_V2,
|
||||
ki18n("(c) 2018 Ivailo Monev"),
|
||||
KLocalizedString(),
|
||||
"http://github.com/fluxer/katana"
|
||||
);
|
||||
|
||||
aboutData.addAuthor(ki18n("Ivailo Monev"),
|
||||
ki18n("Maintainer"),
|
||||
"xakepa10@gmail.com");
|
||||
aboutData.setProgramIconName(QLatin1String("help-browser"));
|
||||
|
||||
KCmdLineArgs::init(argc, argv, &aboutData);
|
||||
KCmdLineOptions option;
|
||||
option.add("+[url]", ki18n("URL to be opened"));
|
||||
KCmdLineArgs::addCmdLineOptions(option);
|
||||
|
||||
KUniqueApplication *kmanapp = new KUniqueApplication();
|
||||
KManMainWindow *kmanwin = new KManMainWindow();
|
||||
kmanwin->show();
|
||||
|
||||
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
|
||||
for (int pos = 0; pos < args->count(); ++pos) {
|
||||
kmanwin->changePath(args->url(pos).prettyUrl());
|
||||
}
|
||||
|
||||
return kmanapp->exec();
|
||||
}
|
Loading…
Add table
Reference in a new issue