File indexing completed on 2025-01-05 03:53:06
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2021-07-24 0007 * Description : MJPEG Stream configuration dialog - Views methods 0008 * 0009 * SPDX-FileCopyrightText: 2021-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 2021 by Quoc Hưng Tran <quochungtran1999 at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "mjpegstreamdlg_p.h" 0017 0018 namespace DigikamGenericMjpegStreamPlugin 0019 { 0020 0021 QWidget* MjpegStreamDlg::setupItemsView() 0022 { 0023 d->albumSupport = (d->settings.iface && d->settings.iface->supportAlbums()); 0024 QWidget* itemsSel = nullptr; 0025 0026 if (d->albumSupport) 0027 { 0028 d->albumSelector = d->settings.iface->albumChooser(this); 0029 itemsSel = d->albumSelector; 0030 0031 connect(d->settings.iface, SIGNAL(signalAlbumChooserSelectionChanged()), 0032 this, SLOT(slotSelectionChanged())); 0033 } 0034 else 0035 { 0036 d->listView = new DItemsList(this); 0037 d->listView->setObjectName(QLatin1String("MjpegStream ImagesList")); 0038 d->listView->setControlButtonsPlacement(DItemsList::ControlButtonsRight); 0039 d->listView->setIface(d->settings.iface); 0040 0041 // Add all items currently loaded in application. 0042 0043 d->listView->loadImagesFromCurrentSelection(); 0044 0045 // Replug the previous shared items list. 0046 0047 d->listView->slotAddImages(d->mngr->itemsList()); 0048 itemsSel = d->listView; 0049 0050 connect(d->listView, SIGNAL(signalImageListChanged()), 0051 this, SLOT(slotSelectionChanged())); 0052 } 0053 0054 return itemsSel; 0055 } 0056 0057 void MjpegStreamDlg::setupServerView() 0058 { 0059 QWidget* const serverSettings = new QWidget(d->tabView); 0060 0061 QLabel* const portLbl = new QLabel(i18nc("@label", "Server Port:"), serverSettings); 0062 d->srvPort = new DIntNumInput(serverSettings); 0063 d->srvPort->setDefaultValue(8080); 0064 d->srvPort->setRange(1025, 65535, 1); 0065 d->srvPort->setWhatsThis(i18nc("@info", "The MJPEG server IP port.")); 0066 portLbl->setBuddy(d->srvPort); 0067 0068 d->startOnStartup = new QCheckBox(i18nc("@option", "Start Server at Startup")); 0069 d->startOnStartup->setWhatsThis(i18nc("@info", "Set this option to turn-on the MJPEG server at application start-up automatically")); 0070 d->startOnStartup->setChecked(true); 0071 0072 // --- 0073 0074 QLabel* const explanation = new QLabel(serverSettings); 0075 explanation->setOpenExternalLinks(true); 0076 explanation->setWordWrap(true); 0077 explanation->setFrameStyle(QFrame::Box | QFrame::Plain); 0078 0079 explanation->setText(i18nc("@info", 0080 "The %1 server allows to share items through the local network using a web browser. " 0081 "Motion JPEG is a video compression format in which each video frame is compressed " 0082 "separately as a JPEG image. MJPEG streams is a standard which allows network clients to be " 0083 "connected without additional module. Most major web browsers and players support MJPEG stream. " 0084 "To access to stream from your browser, just use http://address:port as url, with address " // krazy:exclude=insecurenet 0085 "the MJPEG server IP, and port the server port set in this config dialog.", 0086 QLatin1String("<a href='https://en.wikipedia.org/wiki/Motion_JPEG'>Motion JPEG</a>"))); 0087 0088 d->srvButton = new QPushButton(serverSettings); 0089 d->srvStatus = new QLabel(serverSettings); 0090 d->aStats = new QLabel(serverSettings); 0091 d->separator = new QLabel(QLatin1String(" / "), serverSettings); 0092 d->iStats = new QLabel(serverSettings); 0093 d->progress = new WorkingWidget(serverSettings); 0094 d->srvPreview = new QPushButton(i18nc("@action: button", "Preview..."), serverSettings); 0095 d->srvPreview->setWhatsThis(i18nc("@info", "Press this button to preview the stream on your computer with your browser.")); 0096 0097 QGridLayout* const grid3 = new QGridLayout(serverSettings); 0098 grid3->addWidget(portLbl, 0, 0, 1, 1); 0099 grid3->addWidget(d->srvPort, 0, 1, 1, 1); 0100 grid3->addWidget(d->startOnStartup, 0, 2, 1, 5); 0101 grid3->addWidget(d->srvButton, 1, 0, 1, 1); 0102 grid3->addWidget(d->srvStatus, 1, 1, 1, 1); 0103 grid3->addWidget(d->aStats, 1, 2, 1, 1); 0104 grid3->addWidget(d->separator, 1, 3, 1, 1); 0105 grid3->addWidget(d->iStats, 1, 4, 1, 1); 0106 grid3->addWidget(d->progress, 1, 5, 1, 1); 0107 grid3->addWidget(d->srvPreview, 1, 6, 1, 1); 0108 grid3->addWidget(explanation, 2, 0, 1, 7); 0109 grid3->setSpacing(d->spacing); 0110 0111 d->tabView->insertTab(Private::Server, serverSettings, i18nc("@title", "Server")); 0112 0113 connect(d->srvButton, SIGNAL(clicked()), 0114 this, SLOT(slotToggleMjpegServer())); 0115 0116 connect(d->srvPort, SIGNAL(valueChanged(int)), 0117 this, SLOT(slotSettingsChanged())); 0118 0119 connect(d->srvPreview, SIGNAL(clicked()), 0120 this, SLOT(slotOpenPreview())); 0121 } 0122 0123 void MjpegStreamDlg::setupStreamView() 0124 { 0125 d->streamSettings = new QWidget(d->tabView); 0126 0127 QLabel* const qualityLbl = new QLabel(i18nc("@label", "JPEG Quality:"), d->streamSettings); 0128 d->quality = new DIntNumInput(d->streamSettings); 0129 d->quality->setDefaultValue(75); 0130 d->quality->setRange(50, 100, 1); 0131 d->quality->setWhatsThis(i18nc("@info", "The JPEG quality [50:lower - 100:higher]. " 0132 "Warning: better quality require more network bandwidth")); 0133 0134 qualityLbl->setBuddy(d->quality); 0135 0136 // --- 0137 0138 QLabel* const typeLabel = new QLabel(d->streamSettings); 0139 typeLabel->setWordWrap(false); 0140 typeLabel->setText(i18nc("@label", "JPEG Size:")); 0141 d->typeVal = new DComboBox(d->streamSettings); 0142 d->typeVal->combo()->setEditable(false); 0143 0144 QMap<VidSlideSettings::VidType, QString> map = VidSlideSettings::videoTypeNames(); 0145 QMap<VidSlideSettings::VidType, QString>::const_iterator it = map.constBegin(); 0146 0147 while (it != map.constEnd()) 0148 { 0149 d->typeVal->addItem(it.value(), (int)it.key()); 0150 ++it; 0151 } 0152 0153 d->typeVal->setDefaultIndex(VidSlideSettings::BLUERAY); 0154 d->typeVal->setWhatsThis(i18nc("@info", "The JPEG image size in pixels, using standard screen resolutions. " 0155 "Warning: larger size require more network bandwidth")); 0156 typeLabel->setBuddy(d->typeVal); 0157 0158 // --- 0159 0160 QLabel* const delayLbl = new QLabel(i18nc("@label", "Delay in Seconds:"), d->streamSettings); 0161 d->delay = new DIntNumInput(d->streamSettings); 0162 d->delay->setDefaultValue(5); 0163 d->delay->setRange(1, 3600, 1); 0164 d->delay->setWhatsThis(i18nc("@info", "The delay in seconds between images.")); 0165 delayLbl->setBuddy(d->delay); 0166 0167 QLabel* const rateLbl = new QLabel(i18nc("@label", "Frames by Second:"), d->streamSettings); 0168 d->rate = new DIntNumInput(d->streamSettings); 0169 d->rate->setDefaultValue(10); 0170 d->rate->setRange(5, 24, 1); 0171 d->rate->setWhatsThis(i18nc("@info", "The number of frames by second to render the stream. " 0172 "Warning: larger rate require more network bandwidth")); 0173 rateLbl->setBuddy(d->rate); 0174 0175 d->streamLoop = new QCheckBox(i18nc("@option:check", "Stream in Loop"), d->streamSettings); 0176 d->streamLoop->setChecked(true); 0177 d->streamLoop->setWhatsThis(i18nc("@info", "The MJPEG stream will be played in loop instead once.")); 0178 0179 QGridLayout* const grid2 = new QGridLayout(d->streamSettings); 0180 grid2->addWidget(qualityLbl, 0, 0, 1, 1); 0181 grid2->addWidget(d->quality, 0, 1, 1, 1); 0182 grid2->addWidget(typeLabel, 1, 0, 1, 1); 0183 grid2->addWidget(d->typeVal, 1, 1, 1, 1); 0184 grid2->addWidget(delayLbl, 2, 0, 1, 1); 0185 grid2->addWidget(d->delay, 2, 1, 1, 1); 0186 grid2->addWidget(rateLbl, 3, 0, 1, 1); 0187 grid2->addWidget(d->rate, 3, 1, 1, 1); 0188 grid2->addWidget(d->streamLoop, 4, 0, 1, 2); 0189 grid2->setSpacing(d->spacing); 0190 0191 d->tabView->insertTab(Private::Stream, d->streamSettings, i18nc("@title", "Stream")); 0192 0193 connect(d->delay, SIGNAL(valueChanged(int)), 0194 this, SLOT(slotSettingsChanged())); 0195 0196 connect(d->rate, SIGNAL(valueChanged(int)), 0197 this, SLOT(slotSettingsChanged())); 0198 0199 connect(d->quality, SIGNAL(valueChanged(int)), 0200 this, SLOT(slotSettingsChanged())); 0201 0202 connect(d->streamLoop, SIGNAL(stateChanged(int)), 0203 this, SLOT(slotSettingsChanged())); 0204 0205 connect(d->typeVal, SIGNAL(currentIndexChanged(int)), 0206 this, SLOT(slotSettingsChanged())); 0207 } 0208 0209 void MjpegStreamDlg::setupTransitionView() 0210 { 0211 QWidget* const transitionSettings = new QWidget(d->tabView); 0212 0213 QLabel* const transLabel = new QLabel(transitionSettings); 0214 transLabel->setWordWrap(false); 0215 transLabel->setText(i18nc("@label", "Type:")); 0216 d->transVal = new DComboBox(transitionSettings); 0217 d->transVal->combo()->setEditable(false); 0218 0219 QMap<TransitionMngr::TransType, QString> map4 = TransitionMngr::transitionNames(); 0220 QMap<TransitionMngr::TransType, QString>::const_iterator it4 = map4.constBegin(); 0221 0222 while (it4 != map4.constEnd()) 0223 { 0224 d->transVal->addItem(it4.value(), (int)it4.key()); 0225 ++it4; 0226 } 0227 0228 d->transVal->setDefaultIndex(TransitionMngr::None); 0229 transLabel->setBuddy(d->transVal); 0230 0231 QLabel* const transNote = new QLabel(transitionSettings); 0232 transNote->setWordWrap(true); 0233 transNote->setText(i18nc("@label", "A transition is an visual effect applied between two images. " 0234 "For some effects, the duration can depend of random values and " 0235 "can change while the stream.")); 0236 0237 d->transPreview = new TransitionPreview(transitionSettings); 0238 d->transPreview->setImagesList(QList<QUrl>()); 0239 0240 QGridLayout* const transGrid = new QGridLayout(transitionSettings); 0241 transGrid->setSpacing(d->spacing); 0242 transGrid->addWidget(transLabel, 0, 0, 1, 1); 0243 transGrid->addWidget(d->transVal, 0, 1, 1, 1); 0244 transGrid->addWidget(transNote, 1, 0, 1, 2); 0245 transGrid->addWidget(d->transPreview, 0, 2, 2, 1); 0246 transGrid->setColumnStretch(1, 10); 0247 transGrid->setRowStretch(1, 10); 0248 0249 d->tabView->insertTab(Private::Transition, transitionSettings, i18nc("@title", "Transition")); 0250 0251 connect(d->transVal, SIGNAL(currentIndexChanged(int)), 0252 this, SLOT(slotSettingsChanged())); 0253 } 0254 0255 void MjpegStreamDlg::setupEffectView() 0256 { 0257 QWidget* const effectSettings = new QWidget(d->tabView); 0258 0259 QLabel* const effLabel = new QLabel(effectSettings); 0260 effLabel->setWordWrap(false); 0261 effLabel->setText(i18nc("@label", "Type:")); 0262 d->effVal = new DComboBox(effectSettings); 0263 d->effVal->combo()->setEditable(false); 0264 0265 QMap<EffectMngr::EffectType, QString> map6 = EffectMngr::effectNames(); 0266 QMap<EffectMngr::EffectType, QString>::const_iterator it6 = map6.constBegin(); 0267 0268 while (it6 != map6.constEnd()) 0269 { 0270 d->effVal->insertItem((int)it6.key(), it6.value(), (int)it6.key()); 0271 ++it6; 0272 } 0273 0274 d->effVal->setDefaultIndex(EffectMngr::None); 0275 effLabel->setBuddy(d->effVal); 0276 0277 QLabel* const effNote = new QLabel(effectSettings); 0278 effNote->setWordWrap(true); 0279 effNote->setText(i18nc("@label", "An effect is an visual panning or zooming applied while an image " 0280 "is displayed in MJPEG stream.")); 0281 0282 d->effPreview = new EffectPreview(effectSettings); 0283 d->effPreview->setImagesList(QList<QUrl>()); 0284 0285 QGridLayout* const effGrid = new QGridLayout(effectSettings); 0286 effGrid->setSpacing(d->spacing); 0287 effGrid->addWidget(effLabel, 0, 0, 1, 1); 0288 effGrid->addWidget(d->effVal, 0, 1, 1, 1); 0289 effGrid->addWidget(effNote, 1, 0, 1, 2); 0290 effGrid->addWidget(d->effPreview, 0, 2, 2, 1); 0291 effGrid->setColumnStretch(1, 10); 0292 effGrid->setRowStretch(1, 10); 0293 0294 d->tabView->insertTab(Private::Effect, effectSettings, i18nc("@title", "Effect")); 0295 0296 connect(d->effVal, SIGNAL(currentIndexChanged(int)), 0297 this, SLOT(slotSettingsChanged())); 0298 } 0299 0300 void MjpegStreamDlg::setupOSDView() 0301 { 0302 d->frameOsdWidget = new FrameOsdWidget(d->tabView); 0303 0304 d->tabView->insertTab(Private::OSD, d->frameOsdWidget, 0305 i18nc("@title: On Screen Display", "OSD")); 0306 0307 connect(d->frameOsdWidget, SIGNAL(signalSettingsChanged()), 0308 this, SLOT(slotSettingsChanged())); 0309 } 0310 0311 } // namespace DigikamGenericMjpegStreamPlugin