Go to the documentation of this file.
2 #include <QCoreApplication>
29 #define LOC QString("ChannelEditor: ")
42 if (cardtypes.empty())
45 bool all_v4l = !cardtypes.empty();
46 bool all_asi = !cardtypes.empty();
47 for (
const QString& cardtype : std::as_const(cardtypes))
50 all_asi &= cardtype ==
"ASI";
72 m_currentSortMode(QCoreApplication::translate(
"(Common)",
"Channel Number"))
105 !scanButton || !importIconButton || !transportEditorButton ||
108 LOG(VB_GENERAL, LOG_ERR,
LOC +
"One or more buttons not found in theme.");
113 deleteButton->
SetHelpText(tr(
"Delete all channels on currently selected video source."));
130 query.
prepare(
"SELECT name, sourceid FROM videosource");
136 query.
value(1).toInt());
150 scanButton->
SetHelpText(tr(
"Starts the channel scanner."));
154 if (restoreDataButton)
156 restoreDataButton->
SetHelpText(tr(
"Restore Data from deleted channels."));
162 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Button \"Restore Data\" not found in theme.");
166 importIconButton->
SetHelpText(tr(
"Starts the icon downloader"));
172 tr(
"Allows you to edit the transports directly. "
173 "This is rarely required unless you are using "
174 "a satellite dish and must enter an initial "
175 "frequency to for the channel scanner to try."));
201 for (
int i = 0; i < actions.size() && !handled; i++)
203 const QString&
action = actions[i];
208 else if (
action ==
"DELETE")
210 else if (
action ==
"EDIT")
231 if (!iconpath.isEmpty())
235 QString tmpIcon =
GetConfDir() +
"/channels/" + iconpath;
274 int posOffset = currentIndex - currentTopItemPos;
278 QString currentServiceID;
279 QString currentTransportID;
280 QString currentSourceName;
283 currentServiceID = currentItem->
GetText(
"serviceid");
284 currentTransportID = currentItem->
GetText(
"transportid");
285 currentSourceName = currentItem->
GetText(
"sourcename");
289 QString newchanlabel = tr(
"(Add New Channel)");
291 item->SetText(newchanlabel,
"compoundname");
292 item->SetText(newchanlabel,
"name");
294 bool fAllSources =
true;
296 QString querystr =
"SELECT channel.name, channum, chanid, callsign, icon, "
297 "channel.visible, videosource.name, serviceid, "
298 "dtv_multiplex.frequency, dtv_multiplex.polarity, "
299 "dtv_multiplex.transportid, dtv_multiplex.mod_sys, "
300 "channel.sourceid FROM channel "
301 "LEFT JOIN videosource ON "
302 "(channel.sourceid = videosource.sourceid) "
303 "LEFT JOIN dtv_multiplex ON "
304 "(channel.mplexid = dtv_multiplex.mplexid) "
305 "WHERE deleted IS NULL ";
313 querystr += QString(
"AND channel.sourceid='%1' ")
320 querystr +=
" ORDER BY channel.name, dtv_multiplex.transportid, serviceid, channel.sourceid";
324 querystr +=
" ORDER BY channum + 0, SUBSTRING_INDEX(channum, '_', -1) + 0, dtv_multiplex.transportid, serviceid, channel.sourceid";
328 querystr +=
" ORDER BY serviceid, dtv_multiplex.transportid, channel.sourceid";
332 querystr +=
" ORDER BY dtv_multiplex.frequency, dtv_multiplex.transportid, serviceid, channel.sourceid";
336 querystr +=
" ORDER BY dtv_multiplex.transportid, serviceid";
340 querystr +=
" ORDER BY channel.sourceid, dtv_multiplex.transportid, serviceid";
348 if (query.
exec() && query.
size() > 0)
350 for (; query.
next() ; idx++)
352 QString name = query.
value(0).toString();
353 QString channum = query.
value(1).toString();
354 QString chanid = query.
value(2).toString();
355 QString callsign = query.
value(3).toString();
356 QString icon = query.
value(4).toString();
357 bool visible = query.
value(5).toBool();
358 QString serviceid = query.
value(7).toString();
359 QString frequency = query.
value(8).toString();
360 QString polarity = query.
value(9).toString().toUpper();
361 QString transportid = query.
value(10).toString();
362 QString mod_sys = query.
value(11).toString();
363 QString sourcename =
"Unassigned";
366 if (mod_sys.startsWith(
"DVB-S"))
368 frequency += polarity;
371 QString state =
"normal";
376 if (!query.
value(6).toString().isEmpty())
378 sourcename = query.
value(6).toString();
392 name =
"(Unnamed : " + chanid +
")";
394 QString compoundname = name;
398 if (!channum.isEmpty())
399 compoundname +=
" (" + channum +
")";
403 if (!channum.isEmpty())
404 compoundname = channum +
". " + compoundname;
406 compoundname =
"???. " + compoundname;
410 compoundname +=
" (" + sourcename +
")";
412 bool sel = ((serviceid == currentServiceID ) &&
413 (transportid == currentTransportID) &&
414 (sourcename == currentSourceName ));
415 selidx = (sel) ? idx : selidx;
418 item->SetText(compoundname,
"compoundname");
419 item->SetText(chanid,
"chanid");
420 item->SetText(channum,
"channum");
421 item->SetText(name,
"name");
422 item->SetText(callsign,
"callsign");
423 item->SetText(serviceid,
"serviceid");
424 item->SetText(frequency,
"frequency");
425 item->SetText(transportid,
"transportid");
426 item->SetText(sourcename,
"sourcename");
430 QString tmpIcon =
GetConfDir() +
"/channels/" + icon;
431 item->SetImage(tmpIcon);
432 item->SetImage(tmpIcon,
"icon");
434 item->DisplayState(state,
"status");
444 int newPosition = (!selidx && currentIndex < idx) ? currentIndex : selidx;
447 int newTopPosition = newPosition - posOffset;
450 newTopPosition = std::max(newTopPosition, 0);
455 newTopPosition = std::min(newTopPosition, getCount - getVisibleCount);
465 QString sortName = item->
GetText();
479 QString sourceName = item->
GetText();
480 int sourceID = item->
GetData().toInt();
506 QString message = tr(
"Delete channel '%1'?").arg(item->
GetText(
"name"));
511 if (dialog->Create())
513 dialog->SetData(QVariant::fromValue(item));
514 dialog->SetReturnEvent(
this,
"delsingle");
533 message = tr(
"Delete ALL channels?");
535 message = tr(
"Delete all unassigned channels?");
537 message =tr(
"Delete all channels on %1?").arg(currentLabel);
542 if (dialog->Create())
544 dialog->SetReturnEvent(
this,
"delall");
563 int chanid = item->
GetData().toInt();
584 int chanid = item->
GetData().toInt();
589 QString label = tr(
"Channel Options");
597 menu->SetReturnEvent(
this,
"channelopts");
599 menu->AddButton(tr(
"Edit"));
604 menu->AddButton(tr(
"Delete"));
625 "Select a video source. 'All' cannot be used. "
626 "If there is no video source then create one in the "
627 "'Video sources' menu page and connect a capture card."));
635 "SELECT capturecard.cardid "
637 "WHERE capturecard.sourceid = :SOURCEID AND "
638 " capturecard.hostname = :HOSTNAME");
649 cardid = query.
value(0).toUInt();
656 "Connect video source '%1' to a capture card "
657 "in the 'Input Connections' menu page.")
668 "The capture card(s) connected to video source '%1' "
669 "cannot be used for channel scanning.")
754 channelID = item->
GetData().toInt();
757 QString querystr = QString(
"SELECT channel.name FROM channel "
758 "WHERE chanid='%1'").arg(channelID);
765 channelname = query.
value(0).toString();
768 QString label = tr(
"Icon Import Options");
776 menu->SetReturnEvent(
this,
"iconimportopt");
778 menu->AddButton(tr(
"Download all icons..."));
779 menu->AddButton(tr(
"Rescan for missing icons..."));
780 if (!channelname.isEmpty())
781 menu->AddButtonV(tr(
"Download icon for %1").arg(channelname),
799 QString resultid= dce->GetId();
800 int buttonnum = dce->GetResult();
802 if (resultid ==
"channelopts")
814 else if (resultid ==
"delsingle" && buttonnum == 1)
823 else if (resultid ==
"delall" && buttonnum == 1)
831 query.
prepare(
"TRUNCATE TABLE channel");
835 query.
prepare(
"SELECT sourceid "
837 "GROUP BY sourceid");
847 tmp +=
"'" + query.
value(0).toString() +
"',";
851 query.
prepare(
"TRUNCATE TABLE channel");
856 query.
prepare(QString(
"UPDATE channel "
857 "SET deleted = NOW() "
858 "WHERE deleted IS NULL AND "
859 " sourceid NOT IN (%1)").arg(
tmp));
864 query.
prepare(
"UPDATE channel "
865 "SET deleted = NOW() "
866 "WHERE deleted IS NULL AND sourceid = :SOURCEID");
875 else if (resultid ==
"iconimportopt")
881 QString channelname = dce->GetData().toString();
QString m_sourceFilterName
bool isActive(void) const
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
bool WaitFor(MythConfirmationDialog *dialog)
Blocks until confirmation dialog exits.
QSqlQuery wrapper that fetches a DB connection from the connection pool.
MythScreenStack * GetMainStack()
Image widget, displays a single image or multiple images in sequence.
virtual void setValue(const QString &newValue)
MythUIText * m_transportid
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
static bool DeleteChannel(uint channel_id)
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
QVariant value(int i) const
bool Create(void) override
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Screen in which all other widgets are contained and rendered.
static bool check_cardsource(int sourceid, QString &sourcename)
void Reset(void) override
Reset the image back to the default defined in the theme.
void edit(MythUIButtonListItem *item=nullptr)
MythUIType * GetFocusWidget(void) const
static bool IsAnySourceScanable(void)
static QStringList GetInputTypes(uint chanid)
void customEvent(QEvent *event) override
virtual void addChild(StandardSetting *child)
MythUIButtonList * m_sourceList
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
Basic menu dialog, message and a list of options.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
static void DBError(const QString &where, const MSqlQuery &query)
void SetHelpText(const QString &text)
void BuildFocusList(void)
MythUIButtonList * m_channelList
void SetEnabled(bool enable)
static bool IsUnscanable(uint sourceid)
virtual QString getValue(void) const
void deleteChannels(void)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
A checkbox widget supporting three check states - on,off,half and two conditions - selected and unsel...
static bool IsV4L(const QString &rawtype)
virtual void setLabel(QString str)
void setSourceID(MythUIButtonListItem *item)
void channelIconImport(void)
MythUIText * m_compoundname
All purpose text widget, displays a text string.
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
MythUIText * m_sourcename
Dialog asking for user confirmation. Ok and optional Cancel button.
void SetCheckState(MythUIStateType::StateType state)
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool Create(void) override
void setHideMode(bool hide)
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
virtual void SetText(const QString &text)
static const Type kEventType
void setSortMode(MythUIButtonListItem *item)
MythMainWindow * GetMythMainWindow(void)
MythScreenStack * GetStack(const QString &Stackname)
void transportEditor(void)
static QStringList GetInputTypeNames(uint sourceid)
Get a list of card input types for a source id.
QString GetHostName(void)
QString m_currentSortMode
void itemChanged(MythUIButtonListItem *item)
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
ChannelWizard(int id, int default_sourceid)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
ChannelEditor(MythScreenStack *parent)
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.