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 : qAsConst(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 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();
390 name =
"(Unnamed : " + chanid +
")";
392 QString compoundname = name;
396 if (!channum.isEmpty())
397 compoundname +=
" (" + channum +
")";
401 if (!channum.isEmpty())
402 compoundname = channum +
". " + compoundname;
404 compoundname =
"???. " + compoundname;
408 compoundname +=
" (" + sourcename +
")";
410 bool sel = ((serviceid == currentServiceID ) &&
411 (transportid == currentTransportID) &&
412 (sourcename == currentSourceName ));
413 selidx = (sel) ? idx : selidx;
416 item->SetText(compoundname,
"compoundname");
417 item->SetText(chanid,
"chanid");
418 item->SetText(channum,
"channum");
419 item->SetText(name,
"name");
420 item->SetText(callsign,
"callsign");
421 item->SetText(serviceid,
"serviceid");
422 item->SetText(frequency,
"frequency");
423 item->SetText(transportid,
"transportid");
424 item->SetText(sourcename,
"sourcename");
428 QString tmpIcon =
GetConfDir() +
"/channels/" + icon;
429 item->SetImage(tmpIcon);
430 item->SetImage(tmpIcon,
"icon");
432 item->DisplayState(state,
"status");
442 int newPosition = (!selidx && currentIndex < idx) ? currentIndex : selidx;
445 int newTopPosition = newPosition - posOffset;
448 newTopPosition = std::max(newTopPosition, 0);
453 newTopPosition = std::min(newTopPosition, getCount - getVisibleCount);
463 QString sortName = item->
GetText();
477 QString sourceName = item->
GetText();
478 int sourceID = item->
GetData().toInt();
504 QString message = tr(
"Delete channel '%1'?").arg(item->
GetText(
"name"));
509 if (dialog->Create())
511 dialog->SetData(QVariant::fromValue(item));
512 dialog->SetReturnEvent(
this,
"delsingle");
528 (del_all) ? tr(
"Delete ALL channels?") :
529 ((del_nul) ? tr(
"Delete all unassigned channels?") :
530 tr(
"Delete all channels on %1?").arg(currentLabel));
535 if (dialog->Create())
537 dialog->SetReturnEvent(
this,
"delall");
554 int chanid = item->
GetData().toInt();
573 int chanid = item->
GetData().toInt();
578 QString label = tr(
"Channel Options");
586 menu->SetReturnEvent(
this,
"channelopts");
588 menu->AddButton(tr(
"Edit"));
593 menu->AddButton(tr(
"Delete"));
614 "Select a video source. 'All' cannot be used. "
615 "If there is no video source then create one in the "
616 "'Video sources' menu page and connect a capture card."));
624 "SELECT capturecard.cardid "
626 "WHERE capturecard.sourceid = :SOURCEID AND "
627 " capturecard.hostname = :HOSTNAME");
638 cardid = query.
value(0).toUInt();
645 "Connect video source '%1' to a capture card "
646 "in the 'Input Connections' menu page.")
657 "The capture card(s) connected to video source '%1' "
658 "cannot be used for channel scanning.")
737 channelID = item->
GetData().toInt();
740 QString querystr = QString(
"SELECT channel.name FROM channel "
741 "WHERE chanid='%1'").arg(channelID);
748 channelname = query.
value(0).toString();
751 QString label = tr(
"Icon Import Options");
759 menu->SetReturnEvent(
this,
"iconimportopt");
761 menu->AddButton(tr(
"Download all icons..."));
762 menu->AddButton(tr(
"Rescan for missing icons..."));
763 if (!channelname.isEmpty())
764 menu->AddButtonV(tr(
"Download icon for %1").arg(channelname),
782 QString resultid= dce->GetId();
783 int buttonnum = dce->GetResult();
785 if (resultid ==
"channelopts")
797 else if (resultid ==
"delsingle" && buttonnum == 1)
806 else if (resultid ==
"delall" && buttonnum == 1)
814 query.
prepare(
"TRUNCATE TABLE channel");
818 query.
prepare(
"SELECT sourceid "
820 "GROUP BY sourceid");
830 tmp +=
"'" + query.
value(0).toString() +
"',";
834 query.
prepare(
"TRUNCATE TABLE channel");
839 query.
prepare(QString(
"UPDATE channel "
840 "SET deleted = NOW() "
841 "WHERE deleted IS NULL AND "
842 " sourceid NOT IN (%1)").arg(
tmp));
847 query.
prepare(
"UPDATE channel "
848 "SET deleted = NOW() "
849 "WHERE deleted IS NULL AND sourceid = :SOURCEID");
858 else if (resultid ==
"iconimportopt")
864 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.