File indexing completed on 2025-11-09 04:05:09
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2012-05-28 0007 * Description : Media Server configuration dialog to share a single list of files 0008 * 0009 * SPDX-FileCopyrightText: 2012-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 2017 by Ahmed Fathy <ahmed dot fathi dot abdelmageed at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "dmediaserverdlg.h" 0017 0018 // Qt includes 0019 0020 #include <QVBoxLayout> 0021 #include <QDialogButtonBox> 0022 #include <QApplication> 0023 #include <QMessageBox> 0024 #include <QPushButton> 0025 #include <QGridLayout> 0026 #include <QLabel> 0027 #include <QStyle> 0028 #include <QIcon> 0029 #include <QCheckBox> 0030 0031 // KDE includes 0032 0033 #include <klocalizedstring.h> 0034 #include <ksharedconfig.h> 0035 #include <kconfiggroup.h> 0036 0037 // Local includes 0038 0039 #include "ditemslist.h" 0040 #include "dxmlguiwindow.h" 0041 #include "workingwidget.h" 0042 #include "dmediaservermngr.h" 0043 0044 namespace DigikamGenericMediaServerPlugin 0045 { 0046 0047 class Q_DECL_HIDDEN DMediaServerDlg::Private 0048 { 0049 public: 0050 0051 explicit Private() 0052 : dirty (false), 0053 mngr (DMediaServerMngr::instance()), 0054 srvButton (nullptr), 0055 srvStatus (nullptr), 0056 progress (nullptr), 0057 aStats (nullptr), 0058 separator (nullptr), 0059 iStats (nullptr), 0060 startOnStartup (nullptr), 0061 albumSupport (false), 0062 albumSelector (nullptr), 0063 listView (nullptr), 0064 iface (nullptr), 0065 page (nullptr), 0066 buttons (nullptr) 0067 { 0068 } 0069 0070 bool dirty; 0071 DMediaServerMngr* mngr; 0072 QPushButton* srvButton; 0073 QLabel* srvStatus; 0074 WorkingWidget* progress; 0075 QLabel* aStats; 0076 QLabel* separator; 0077 QLabel* iStats; 0078 QCheckBox* startOnStartup; 0079 bool albumSupport; 0080 QWidget* albumSelector; 0081 DItemsList* listView; 0082 DInfoInterface* iface; 0083 QWidget* page; 0084 QDialogButtonBox* buttons; 0085 }; 0086 0087 DMediaServerDlg::DMediaServerDlg(QObject* const /*parent*/, 0088 DInfoInterface* const iface) 0089 : DPluginDialog(nullptr, DMediaServerMngr::instance()->configGroupName()), 0090 d (new Private) 0091 { 0092 setWindowTitle(i18nc("@title:window", "Share Files With DLNA Media Server")); 0093 0094 d->iface = iface; 0095 0096 // NOTE: We overwrite the default albums chooser object name for load save check items state between sessions. 0097 // The goal is not mix these settings with other export tools. 0098 0099 d->iface->setObjectName(QLatin1String("SetupMediaServerIface")); 0100 0101 m_buttons->addButton(QDialogButtonBox::Cancel); 0102 m_buttons->addButton(QDialogButtonBox::Ok); 0103 m_buttons->button(QDialogButtonBox::Ok)->setDefault(true); 0104 d->page = new QWidget(this); 0105 QVBoxLayout* const vbx = new QVBoxLayout(this); 0106 vbx->addWidget(d->page); 0107 vbx->addWidget(m_buttons); 0108 setLayout(vbx); 0109 setModal(false); 0110 0111 // ------------------- 0112 0113 QGridLayout* const grid = new QGridLayout(d->page); 0114 d->albumSupport = (d->iface && d->iface->supportAlbums()); 0115 0116 if (d->albumSupport) 0117 { 0118 d->albumSelector = d->iface->albumChooser(this); 0119 grid->addWidget(d->albumSelector, 0, 0, 1, 6); 0120 0121 connect(d->iface, SIGNAL(signalAlbumChooserSelectionChanged()), 0122 this, SLOT(slotSelectionChanged())); 0123 } 0124 else 0125 { 0126 d->listView = new DItemsList(d->page); 0127 d->listView->setObjectName(QLatin1String("MediaServer ImagesList")); 0128 d->listView->setControlButtonsPlacement(DItemsList::ControlButtonsRight); 0129 d->listView->setIface(d->iface); 0130 0131 // Add all items currently loaded in application. 0132 0133 d->listView->loadImagesFromCurrentSelection(); 0134 0135 // Replug the previous shared items list. 0136 0137 d->listView->slotAddImages(d->mngr->itemsList()); 0138 grid->addWidget(d->listView, 0, 0, 1, 6); 0139 0140 connect(d->listView, SIGNAL(signalImageListChanged()), 0141 this, SLOT(slotSelectionChanged())); 0142 } 0143 0144 // ------------------- 0145 0146 const int spacing = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0147 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing)); 0148 0149 d->startOnStartup = new QCheckBox(i18nc("@option", "Start Server at Startup")); 0150 d->startOnStartup->setWhatsThis(i18nc("@info", "Set this option to turn-on the DLNA server at application start-up automatically")); 0151 d->startOnStartup->setChecked(true); 0152 0153 d->srvButton = new QPushButton(this); 0154 d->srvStatus = new QLabel(this); 0155 d->progress = new WorkingWidget(this); 0156 d->aStats = new QLabel(this); 0157 d->separator = new QLabel(QLatin1String(" / "), this); 0158 d->iStats = new QLabel(this); 0159 0160 QLabel* const explanation = new QLabel(this); 0161 explanation->setOpenExternalLinks(true); 0162 explanation->setWordWrap(true); 0163 explanation->setFrameStyle(QFrame::Box | QFrame::Plain); 0164 QString txt; 0165 0166 explanation->setText(i18nc("@info", 0167 "The media server allows to share items through the local network " 0168 "using %1 standard and %2 protocol. " 0169 "Many kind of electronic devices can support DLNA, as tablets, cellulars, TV, etc.\n\n" 0170 "Note: depending of the network features and the configuration, " 0171 "the delay to discover the server on client devices can take a while.", 0172 QLatin1String("<a href='https://en.wikipedia.org/wiki/Digital_Living_Network_Alliance'>DLNA</a>"), 0173 QLatin1String("<a href='https://en.wikipedia.org/wiki/Universal_Plug_and_Play'>UPNP</a>"))); 0174 0175 grid->addWidget(d->startOnStartup, 1, 0, 1, 6); 0176 grid->addWidget(d->srvButton, 2, 0, 1, 1); 0177 grid->addWidget(d->srvStatus, 2, 1, 1, 1); 0178 grid->addWidget(d->aStats, 2, 2, 1, 1); 0179 grid->addWidget(d->separator, 2, 3, 1, 1); 0180 grid->addWidget(d->iStats, 2, 4, 1, 1); 0181 grid->addWidget(d->progress, 2, 5, 1, 1); 0182 grid->addWidget(explanation, 3, 0, 1, 6); 0183 grid->setColumnStretch(1, 10); 0184 grid->setRowStretch(0, 10); 0185 grid->setSpacing(spacing); 0186 0187 // -------------------------------------------------------- 0188 0189 connect(d->srvButton, SIGNAL(clicked()), 0190 this, SLOT(slotToggleMediaServer())); 0191 0192 connect(m_buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, 0193 this, &DMediaServerDlg::reject); 0194 0195 connect(m_buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked, 0196 this, &DMediaServerDlg::accept); 0197 0198 // ------------------- 0199 0200 readSettings(); 0201 } 0202 0203 DMediaServerDlg::~DMediaServerDlg() 0204 { 0205 delete d; 0206 } 0207 0208 void DMediaServerDlg::accept() 0209 { 0210 if (d->dirty) 0211 { 0212 bool empty = false; 0213 0214 if (d->albumSupport) 0215 { 0216 empty = d->iface->albumChooserItems().isEmpty(); 0217 } 0218 else 0219 { 0220 empty = d->listView->imageUrls().isEmpty(); 0221 } 0222 0223 if (!empty) 0224 { 0225 int rc = QMessageBox::question(this, i18nc("@title:window", "Media Server Contents"), 0226 i18nc("@info", "The items list to share has changed. " 0227 "Do you want to start now the media server with this contents?")); 0228 if (rc == QMessageBox::Yes) 0229 { 0230 startMediaServer(); 0231 } 0232 } 0233 } 0234 0235 saveSettings(); 0236 QDialog::accept(); 0237 } 0238 0239 void DMediaServerDlg::readSettings() 0240 { 0241 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0242 KConfigGroup group = config->group(d->mngr->configGroupName()); 0243 0244 d->startOnStartup->setChecked(group.readEntry(d->mngr->configStartServerOnStartupEntry(), false)); 0245 0246 updateServerStatus(); 0247 } 0248 0249 void DMediaServerDlg::saveSettings() 0250 { 0251 setMediaServerContents(); 0252 0253 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0254 KConfigGroup group = config->group(d->mngr->configGroupName()); 0255 group.writeEntry(d->mngr->configStartServerOnStartupEntry(), d->startOnStartup->isChecked()); 0256 config->sync(); 0257 } 0258 0259 void DMediaServerDlg::updateServerStatus() 0260 { 0261 if (d->mngr->isRunning()) 0262 { 0263 d->srvStatus->setText(i18nc("@label", "Server is running")); 0264 d->aStats->setText(i18ncp("@info", "1 album shared", "%1 albums shared", d->mngr->albumsShared())); 0265 d->separator->setVisible(true); 0266 d->iStats->setText(i18ncp("@info", "1 item shared", "%1 items shared", d->mngr->itemsShared())); 0267 d->srvButton->setText(i18nc("@action: button", "Stop")); 0268 d->srvButton->setIcon(QIcon::fromTheme(QLatin1String("media-playback-stop"))); 0269 d->progress->toggleTimer(true); 0270 d->progress->setVisible(true); 0271 } 0272 else 0273 { 0274 d->srvStatus->setText(i18nc("@label", "Server is not running")); 0275 d->aStats->clear(); 0276 d->separator->setVisible(false); 0277 d->iStats->clear(); 0278 d->srvButton->setText(i18nc("@action: button", "Start")); 0279 d->srvButton->setIcon(QIcon::fromTheme(QLatin1String("media-playback-start"))); 0280 d->progress->toggleTimer(false); 0281 d->progress->setVisible(false); 0282 } 0283 } 0284 0285 bool DMediaServerDlg::setMediaServerContents() 0286 { 0287 if (d->albumSupport) 0288 { 0289 DInfoInterface::DAlbumIDs albums = d->iface->albumChooserItems(); 0290 MediaServerMap map; 0291 0292 Q_FOREACH (int id, albums) 0293 { 0294 DAlbumInfo anf(d->iface->albumInfo(id)); 0295 map.insert(anf.title(), d->iface->albumItems(id)); 0296 } 0297 0298 if (map.isEmpty()) 0299 { 0300 QMessageBox::information(this, i18nc("@title:window", "Media Server Contents"), 0301 i18nc("@info", "There is no collection to share with the current selection...")); 0302 return false; 0303 } 0304 0305 d->mngr->setCollectionMap(map); 0306 } 0307 else 0308 { 0309 QList<QUrl> urls = d->listView->imageUrls(); 0310 0311 if (urls.isEmpty()) 0312 { 0313 QMessageBox::information(this, i18nc("@title:window", "Media Server Contents"), 0314 i18nc("@info", "There is no item to share with the current selection...")); 0315 0316 return false; 0317 } 0318 0319 d->mngr->setItemsList(i18nc("@info", "Shared Items"), urls); 0320 } 0321 0322 return true; 0323 } 0324 0325 void DMediaServerDlg::startMediaServer() 0326 { 0327 if (d->dirty) 0328 { 0329 d->dirty = false; 0330 } 0331 0332 if (!setMediaServerContents()) 0333 { 0334 return; 0335 } 0336 0337 if (!d->mngr->startMediaServer()) 0338 { 0339 QMessageBox::warning(this, i18nc("@title:window", "Starting Media Server"), 0340 i18nc("@info", "An error occurs while to start Media Server...")); 0341 } 0342 else 0343 { 0344 d->mngr->mediaServerNotification(true); 0345 } 0346 0347 updateServerStatus(); 0348 } 0349 0350 void DMediaServerDlg::slotSelectionChanged() 0351 { 0352 d->dirty = true; 0353 } 0354 0355 void DMediaServerDlg::slotToggleMediaServer() 0356 { 0357 if (!d->mngr->isRunning()) 0358 { 0359 startMediaServer(); 0360 } 0361 else 0362 { 0363 d->mngr->cleanUp(); 0364 updateServerStatus(); 0365 } 0366 } 0367 0368 } // namespace DigikamGenericMediaServerPlugin 0369 0370 #include "moc_dmediaserverdlg.cpp"