/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include #include #include #include #include #include "shemov.h" #include "configurationdialog.h" #include "statisticsdialog.h" #include "smglobals.h" #include "newmoviewizard.h" #include "consistencycheck.h" #include "mappingtableeditor.h" #include "mappingtablemodel.h" #include "dbanalyzer.h" #include "newpicsdialog.h" #include "pictureswidget.h" #include "picturelistview.h" #include "archiveview.h" #include "archivebrowser.h" #include "searchdialog.h" #include "randomtab.h" #include "fswidget.h" #include "moviewidget.h" #include "helper.h" SheMov::SheMov(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) /*, mOpenWithGroupFS(0), mOpenWithGroupAV(0) */ { //application icon qApp->setWindowIcon(QIcon(":/shemov.png")); createPalette(); setAttribute(Qt::WA_DeleteOnClose); QSplashScreen splash(QPixmap(":/shemov_splash2.png")); splash.show(); //init database as early as possible splash.showMessage(tr("Initializing globals..."), Qt::AlignHCenter, Qt::yellow); qApp->processEvents(); (void) SmGlobals::instance(); mAnalyzeActorsA = new QAction(tr("Actors..."), this); connect(mAnalyzeActorsA, &QAction::triggered, this, &SheMov::analyzeActors); mAnalyzeGenresA = new QAction(tr("Genres..."), this); connect(mAnalyzeGenresA, &QAction::triggered, this, &SheMov::analyzeGenres); mAnalyzeSeriesA = new QAction(tr("Series..."), this); connect(mAnalyzeSeriesA, &QAction::triggered, this, &SheMov::analyzeSeries); mAnalyzePartsA = new QAction(tr("Series Parts..."), this); connect(mAnalyzePartsA, &QAction::triggered, this, &SheMov::analyzeParts); mConsistencyA = new QAction(tr("Check consisteny..."), this); connect(mConsistencyA, &QAction::triggered, this, &SheMov::checkConsistency); /*mSearchDialogA = new QAction(tr("Search..."), this); mSearchDialogA->setShortcut(tr("CTRL+f")); connect(mSearchDialogA, &QAction::triggered, mSearchDialog, &SearchDialog::show);*/ mQuitA = new QAction(tr("Quit"), this); mQuitA->setShortcut(tr("CTRL+q")); connect(mQuitA, &QAction::triggered, qApp, &QApplication::closeAllWindows); mConfigA = new QAction(QIcon(":/chastity_belt.png"), tr("Configure..."), this); connect(mConfigA, &QAction::triggered, this, &SheMov::configure); QString aboutLabel = QString(tr("About %1...")).arg(qApp->applicationName()); mAboutShemovA = new QAction(aboutLabel, this); connect(mAboutShemovA, &QAction::triggered, this, &SheMov::aboutShemov); mAboutQtA = new QAction(tr("About Qt..."), this); connect(mAboutQtA, &QAction::triggered, qApp, &QApplication::aboutQt); mStatisticsA = new QAction(tr("Some statistics..."), this); connect(mStatisticsA, &QAction::triggered, this, &SheMov::showStatistics); //global menu QAction *globalMenuA = new QAction(Helper::icon(QColor(0, 0, 0, 0), Qt::black, QChar(0x26A4), true, false), tr("Global"), this); QMenu *globalMenu = new QMenu; globalMenu->addAction(mConsistencyA); globalMenu->addSeparator(); QMenu *analyzeMenu = new QMenu; analyzeMenu->addAction(mAnalyzeActorsA); analyzeMenu->addAction(mAnalyzeGenresA); analyzeMenu->addAction(mAnalyzePartsA); analyzeMenu->addAction(mAnalyzeSeriesA); QAction *analyzeMenuA = new QAction(tr("Analyze"), this); analyzeMenuA->setMenu(analyzeMenu); globalMenu->addAction(analyzeMenuA); globalMenu->addSeparator(); globalMenu->addAction(mConfigA); globalMenu->addAction(mStatisticsA); globalMenu->addSeparator(); globalMenu->addAction(mAboutQtA); globalMenu->addAction(mAboutShemovA); globalMenu->addSeparator(); globalMenu->addAction(mQuitA); globalMenuA->setMenu(globalMenu); SmGlobals::instance()->setGlobalAction(globalMenuA); //FileSystemWidget + TabWidget splash.showMessage(tr("Constructing Filemanager..."), Qt::AlignHCenter, Qt::yellow); qApp->processEvents(); mTab = new QTabWidget; mFileWidget = new FSWidget; mTab->addTab(mFileWidget, tr("FS")); connect(mFileWidget, &FSWidget::message, this, &SheMov::statusbarMessage); connect(mFileWidget, &FSWidget::selectionChanged, [=](int count, qint64 size, qint64 duration) { updateSelectedCount(count); setSize(size); setDuration(duration, false); }); connect(mFileWidget, &FSWidget::needRefreshFs, this, &SheMov::setFsFree); connect(mFileWidget, &FSWidget::needConfig, this, &SheMov::configure); connect(mFileWidget, &FSWidget::needTitleChange, this, &SheMov::setWindowTitle); //MovieWidget splash.showMessage(tr("Constructing MovieWidget..."), Qt::AlignHCenter, Qt::yellow); qApp->processEvents(); mMovieWidget = new MovieWidget; mTab->addTab(mMovieWidget, "MW"); connect(mMovieWidget, &MovieWidget::needTitleChange, this, &SheMov::setWindowTitle); //pictures splash.showMessage(tr("Creating Picture Archive..."), Qt::AlignHCenter, Qt::yellow); qApp->processEvents(); mPicWidget = new PicturesWidget; mTab->addTab(mPicWidget, tr("Pictures")); connect(mPicWidget, &PicturesWidget::needWindowTitleChange, this, &SheMov::setWindowTitle); connect(mPicWidget->picView(), &PictureListView::newMappings, this, &SheMov::statusbarMessage); connect(mPicWidget->picView(), &PictureListView::numSelected, this, &SheMov::updateSelectedCount); connect(mPicWidget->picView(), &PictureListView::selectedSize, this, &SheMov::setSize); PictureViewer2 *picViewer = SmGlobals::instance()->pictureViewer(); //archivebrower splash.showMessage(tr("Creating Archive Browser..."), Qt::AlignHCenter, Qt::yellow); qApp->processEvents(); mArchiveBrowser = new ArchiveBrowser; mTab->addTab(mArchiveBrowser, tr("Archive Browser")); connect(mArchiveBrowser, &ArchiveBrowser::sizeChanged, this, &SheMov::setSize); connect(mArchiveBrowser, &ArchiveBrowser::itemCountChanged, this, &SheMov::updateSelectedCount); connect(mArchiveBrowser, &ArchiveBrowser::needFSFreeUpdate, this, &SheMov::setFsFree); //randomtab splash.showMessage(tr("Creating Random Browser..."), Qt::AlignHCenter, Qt::yellow); qApp->processEvents(); mRandomTab = new RandomTab; connect(mRandomTab, &RandomTab::configure, this, &SheMov::configure); mTab->addTab(mRandomTab, tr("Random")); //misc dialogs splash.showMessage(tr("Creating misc. Dialogs..."), Qt::AlignHCenter, Qt::yellow); qApp->processEvents(); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(mTab); splash.showMessage(tr("Creating Menus and Statusbar..."), Qt::AlignHCenter, Qt::yellow); qApp->processEvents(); createStatusbar(); createMenus(); setFsFree(); splash.showMessage(tr("Finishing..."), Qt::AlignHCenter, Qt::yellow); qApp->processEvents(); connect(mTab, &QTabWidget::currentChanged, this, &SheMov::tabChanged); connect(this, &SheMov::configChanged, picViewer, &PictureViewer2::readSettings); connect(this, &SheMov::configChanged, mFileWidget, &FSWidget::readSettings); QWidget *centralWidget = new QWidget; centralWidget->setLayout(mainLayout); setCentralWidget(centralWidget); show(); splash.finish(this); mPicWidget->readSettings(); mArchiveBrowser->readConfig(); readSettings(); setWindowState(Qt::WindowMaximized); } void SheMov::closeEvent(QCloseEvent *event){ mPicWidget->picViewer2()->writeSettings(); mPicWidget->writeSettings(); mArchiveBrowser->writeSettings(); writeSettings(); SmGlobals *globals = SmGlobals::instance(); delete globals; QSqlDatabase::database("treedb").close(); qApp->closeAllWindows(); event->accept(); } void SheMov::updateSelectedCount(int count){ mSelectedItems->setText(QString::number(count)); } void SheMov::statusbarMessage(const QString &message){ statusBar()->showMessage(message); } void SheMov::configure(){ ConfigurationDialog dlg(this); dlg.exec(); createPalette(); emit configChanged(); } void SheMov::tabChanged(int newTab){ if(newTab == FileManager || newTab == Movies || newTab == Pictures || newTab == ArchiveBrowserTab){ menuBar()->setVisible(false); }else{ menuBar()->setVisible(true); } mRandomEditMenuA->setVisible(newTab == RandomDisp); statusbarMessage(QString()); switch(newTab){ case FileManager: setWindowTitle(mFileWidget->wTitle); break; case Movies: setWindowTitle(mMovieWidget->wTitle); break; case Pictures: mPicWidget->constructWindowTitle(); setDuration(0x0, false); break; case ArchiveBrowserTab: setWindowTitle(tr("Archive Browser")); break; default: setDuration(0x0, false); ;; } } void SheMov::setFsFree(){ struct statfs buf; QSettings s; QString dir = s.value("paths/archivedir").toString(); int success = statfs(qPrintable(dir), &buf); if(success == -1){ mFsFree->setText(tr("Error")); return; } int blocksize = buf.f_bsize; int free = buf.f_bfree; int avail = buf.f_blocks; int used = avail - free; qreal freep = free * 100.0 / avail; qreal usedp = used * 100.0 / avail; QFont f = qApp->font(); QFontMetrics fm(f); int height = fm.height() + 3; QImage img(100, height, QImage::Format_ARGB32); img.fill(0); QPainter p(&img); p.setBrush(QBrush(Qt::red)); p.setPen(QPen(Qt::blue)); p.drawRect(QRectF(0, 0, usedp, height)); p.setBrush(QBrush(Qt::green)); p.drawRect(QRectF(usedp, 0, freep, height)); quint64 freeb = static_cast(free) * blocksize; qreal freegib = freeb / 1024.0 / 1024.0 / 1024.0; int freeRounded = qRound(freegib); QString freeString = QString("%1 GiB free").arg(QString::number(freeRounded)); QSize stringSize = fm.size(Qt::TextSingleLine, freeString); int startx = (100 - stringSize.width()) / 2; int starty = (height - stringSize.height()) / 2 + fm.ascent(); p.drawText(QPoint(startx, starty), freeString); mFsFree->setPixmap(QPixmap::fromImage(img)); } void SheMov::aboutShemov(){ QString aboutLabel = QString(tr("About %1")).arg(qApp->applicationName()); QString aboutText = QString(tr("

%1 is a little application to keep track of your pr0n movie collection, though it isn't limited to pr0n movies.

")).arg(qApp->applicationName()); aboutText.append(""); aboutText.append(tr("Sissy herself")); aboutText.append(QString(tr("")).arg(qApp->organizationName())); aboutText.append(QString(tr("")).arg(qApp->applicationVersion())); aboutText.append(QString(tr(""))); aboutText.append(tr("
Author
Organization%1
Version%1
Build:/* __debug build__ */
Dependencies
    ")); aboutText.append(tr("
  • Qt (thanks for this great library)
  • ")); aboutText.append(tr("
  • libmagic for figuring out the file type
  • ")); aboutText.append("
"); QMessageBox::about(this, aboutLabel, aboutText); } void SheMov::showStatistics(){ StatisticsDialog dlg(this); dlg.exec(); } void SheMov::setSize(qint64 size){ QLocale l; QString val; qint64 free = DVDSIZE - size; QString selectedSize = l.toString(size); QString freeSize = l.toString(free); if(size < DVDSIZE){ val = QString("%1 (%2)").arg(selectedSize).arg(freeSize); }else{ val = QString("%1 (%2)").arg(selectedSize).arg(freeSize); } mSelectedSize->setText(val); } void SheMov::setDuration(qint64 dur, bool maybeMore){ Helper::Duration d(dur); QString t = d.toString(); if(maybeMore){ t.append("+"); } mSelectedDuration->setText(t); } void SheMov::createStatusbar(){ QLabel *selDurL = new QLabel(tr("Duration")); mSelectedDuration = new QLabel("00:00:00"); mSelectedDuration->setFrameStyle(QFrame::Panel | QFrame::Sunken); statusBar()->addPermanentWidget(selDurL); statusBar()->addPermanentWidget(mSelectedDuration); QLabel *selSizeL = new QLabel(tr("Sel. Size")); mSelectedSize = new QLabel(tr("nothing selected yet")); mSelectedSize->setFrameStyle(QFrame::Panel | QFrame::Sunken); statusBar()->addPermanentWidget(selSizeL); statusBar()->addPermanentWidget(mSelectedSize); QLabel *selCountL = new QLabel(tr("Sel. Items")); mSelectedItems = new QLabel("0"); mSelectedItems->setFrameStyle(QFrame::Panel | QFrame::Sunken); statusBar()->addPermanentWidget(selCountL); statusBar()->addPermanentWidget(mSelectedItems); QLabel *freeL = new QLabel(tr("Free space")); mFsFree = new QLabel(tr("calculating...")); mFsFree->setFrameStyle(QFrame::Panel | QFrame::Sunken); statusBar()->addPermanentWidget(freeL); statusBar()->addPermanentWidget(mFsFree); } void SheMov::createMenus(){ //FIXME! //fileMenu->addAction(mConsistencyA); QMenu *analyzeMenu = new QMenu(tr("Analyze"), this); analyzeMenu->addAction(mAnalyzeActorsA); analyzeMenu->addAction(mAnalyzeGenresA); analyzeMenu->addAction(mAnalyzeSeriesA); analyzeMenu->addAction(mAnalyzePartsA); QMenu *helpMenu = new QMenu(tr("&Help"), this); helpMenu->addAction(mAboutShemovA); helpMenu->addAction(mAboutQtA); helpMenu->addSeparator(); helpMenu->addAction(mStatisticsA); menuBar()->addMenu(helpMenu); // Random mRandomEditMenu = mRandomTab->editMenu(); mRandomEditMenuA = menuBar()->addMenu(mRandomEditMenu); } void SheMov::writeSettings(){ QSettings s; s.setValue("ui/selectedtab", mTab->currentIndex()); } void SheMov::readSettings(){ QSettings s; int currentTab = s.value("ui/selectedtab", 0).toInt(); if(currentTab < mTab->count() && currentTab != mTab->currentIndex()){ mTab->setCurrentIndex(currentTab); } tabChanged(currentTab); createPalette(); } void SheMov::createPalette(){ QSettings s; bool alternate = s.value("ui/allowalternate").toBool(); QPalette pal(palette()); if(alternate){ QVariant basecolor = s.value("ui/basecolor"); QVariant alternatecolor = s.value("ui/alternatecolor"); pal.setColor(QPalette::Base, basecolor.value()); pal.setColor(QPalette::AlternateBase, alternatecolor.value()); }else{ pal.setColor(QPalette::Base, Qt::white); pal.setColor(QPalette::AlternateBase, Qt::white); } qApp->setPalette(pal); } void SheMov::analyzeActors(){ EmptyActorsDialog d(tr("Actors"), this); d.populate(); d.exec(); } void SheMov::analyzeGenres(){ EmptyGenresDialog d(tr("Genres"), this); d.populate(); d.exec(); } void SheMov::analyzeSeries(){ EmptySeriesDialog d(tr("Series"), this); d.populate(); d.exec(); } void SheMov::analyzeParts(){ EmptyPartsDialog d(tr("Series Parts"), this); d.populate(); d.exec(); } void SheMov::checkConsistency(){ ConsistencyCheck c; c.exec(); } void SheMov::toggleHover(QObject *object){ QAction *action = qobject_cast(object); if(action){ QSettings s; QString toSet = action->data().toString(); bool checked = action->isChecked(); s.setValue(toSet, checked); emit configChanged(); } }