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";
69 m_currentSortMode(QCoreApplication::translate(
"(Common)",
"Channel Number"))
102 !scanButton || !importIconButton || !transportEditorButton ||
105 LOG(VB_GENERAL, LOG_ERR,
LOC +
"One or more buttons not found in theme.");
110 deleteButton->
SetHelpText(tr(
"Delete all channels on currently selected video source."));
127 query.
prepare(
"SELECT name, sourceid FROM videosource");
133 query.
value(1).toInt());
147 scanButton->
SetHelpText(tr(
"Starts the channel scanner."));
151 if (restoreDataButton)
153 restoreDataButton->
SetHelpText(tr(
"Restore Data from deleted channels."));
159 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Button \"Restore Data\" not found in theme.");
163 importIconButton->
SetHelpText(tr(
"Starts the icon downloader"));
169 tr(
"Allows you to edit the transports directly. "
170 "This is rarely required unless you are using "
171 "a satellite dish and must enter an initial "
172 "frequency to for the channel scanner to try."));
198 for (
int i = 0; i < actions.size() && !handled; i++)
200 QString
action = actions[i];
205 else if (
action ==
"DELETE")
207 else if (
action ==
"EDIT")
228 if (!iconpath.isEmpty())
232 QString tmpIcon =
GetConfDir() +
"/channels/" + iconpath;
271 int posOffset = currentIndex - currentTopItemPos;
275 QString currentServiceID;
276 QString currentTransportID;
277 QString currentSourceName;
280 currentServiceID = currentItem->
GetText(
"serviceid");
281 currentTransportID = currentItem->
GetText(
"transportid");
282 currentSourceName = currentItem->
GetText(
"sourcename");
286 QString newchanlabel = tr(
"(Add New Channel)");
288 item->SetText(newchanlabel,
"compoundname");
289 item->SetText(newchanlabel,
"name");
291 bool fAllSources =
true;
293 QString querystr =
"SELECT channel.name, channum, chanid, callsign, icon, "
294 "channel.visible, videosource.name, serviceid, "
295 "dtv_multiplex.frequency, dtv_multiplex.polarity, "
296 "dtv_multiplex.transportid, dtv_multiplex.mod_sys, "
297 "channel.sourceid FROM channel "
298 "LEFT JOIN videosource ON "
299 "(channel.sourceid = videosource.sourceid) "
300 "LEFT JOIN dtv_multiplex ON "
301 "(channel.mplexid = dtv_multiplex.mplexid) "
302 "WHERE deleted IS NULL ";
310 querystr += QString(
"AND channel.sourceid='%1' ")
317 querystr +=
" ORDER BY channel.name, dtv_multiplex.transportid, serviceid, channel.sourceid";
321 querystr +=
" ORDER BY channum + 0, SUBSTRING_INDEX(channum, '_', -1) + 0, dtv_multiplex.transportid, serviceid, channel.sourceid";
325 querystr +=
" ORDER BY serviceid, dtv_multiplex.transportid, channel.sourceid";
329 querystr +=
" ORDER BY dtv_multiplex.frequency, dtv_multiplex.transportid, serviceid, channel.sourceid";
333 querystr +=
" ORDER BY dtv_multiplex.transportid, serviceid";
337 querystr +=
" ORDER BY channel.sourceid, dtv_multiplex.transportid, serviceid";
345 if (query.
exec() && query.
size() > 0)
347 for (; query.
next() ; idx++)
349 QString name = query.
value(0).toString();
350 QString channum = query.
value(1).toString();
351 QString chanid = query.
value(2).toString();
352 QString callsign = query.
value(3).toString();
353 QString icon = query.
value(4).toString();
354 bool visible = query.
value(5).toBool();
355 QString serviceid = query.
value(7).toString();
356 QString frequency = query.
value(8).toString();
357 QString polarity = query.
value(9).toString().toUpper();
358 QString transportid = query.
value(10).toString();
359 QString mod_sys = query.
value(11).toString();
360 QString sourcename =
"Unassigned";
363 if (mod_sys.startsWith(
"DVB-S"))
365 frequency += polarity;
368 QString state =
"normal";
373 if (!query.
value(6).toString().isEmpty())
375 sourcename = query.
value(6).toString();
387 name =
"(Unnamed : " + chanid +
")";
389 QString compoundname = name;
393 if (!channum.isEmpty())
394 compoundname +=
" (" + channum +
")";
398 if (!channum.isEmpty())
399 compoundname = channum +
". " + compoundname;
401 compoundname =
"???. " + compoundname;
405 compoundname +=
" (" + sourcename +
")";
407 bool sel = ((serviceid == currentServiceID ) &&
408 (transportid == currentTransportID) &&
409 (sourcename == currentSourceName ));
410 selidx = (sel) ? idx : selidx;
413 item->SetText(compoundname,
"compoundname");
414 item->SetText(chanid,
"chanid");
415 item->SetText(channum,
"channum");
416 item->SetText(name,
"name");
417 item->SetText(callsign,
"callsign");
418 item->SetText(serviceid,
"serviceid");
419 item->SetText(frequency,
"frequency");
420 item->SetText(transportid,
"transportid");
421 item->SetText(sourcename,
"sourcename");
425 QString tmpIcon =
GetConfDir() +
"/channels/" + icon;
426 item->SetImage(tmpIcon);
427 item->SetImage(tmpIcon,
"icon");
429 item->DisplayState(state,
"status");
439 int newPosition = (!selidx && currentIndex < idx) ? currentIndex : selidx;
442 int newTopPosition = newPosition - posOffset;
445 newTopPosition = std::max(newTopPosition, 0);
450 newTopPosition = std::min(newTopPosition, getCount - getVisibleCount);
460 QString sortName = item->
GetText();
474 QString sourceName = item->
GetText();
475 int sourceID = item->
GetData().toInt();
501 QString message = tr(
"Delete channel '%1'?").arg(item->
GetText(
"name"));
506 if (dialog->Create())
508 dialog->SetData(QVariant::fromValue(item));
509 dialog->SetReturnEvent(
this,
"delsingle");
525 (del_all) ? tr(
"Delete ALL channels?") :
526 ((del_nul) ? tr(
"Delete all unassigned channels?") :
527 tr(
"Delete all channels on %1?").arg(currentLabel));
532 if (dialog->Create())
534 dialog->SetReturnEvent(
this,
"delall");
551 int chanid = item->
GetData().toInt();
570 int chanid = item->
GetData().toInt();
575 QString label = tr(
"Channel Options");
583 menu->SetReturnEvent(
this,
"channelopts");
585 menu->AddButton(tr(
"Edit"));
590 menu->AddButton(tr(
"Delete"));
611 "Select a video source. 'All' cannot be used. "
612 "If there is no video source then create one in the "
613 "'Video sources' menu page and connect a capture card."));
621 "SELECT capturecard.cardid "
623 "WHERE capturecard.sourceid = :SOURCEID AND "
624 " capturecard.hostname = :HOSTNAME");
635 cardid = query.
value(0).toUInt();
642 "Connect video source '%1' to a capture card "
643 "in the 'Input Connections' menu page.")
654 "The capture card(s) connected to video source '%1' "
655 "cannot be used for channel scanning.")
734 channelID = item->
GetData().toInt();
737 QString querystr = QString(
"SELECT channel.name FROM channel "
738 "WHERE chanid='%1'").arg(channelID);
745 channelname = query.
value(0).toString();
748 QString label = tr(
"Icon Import Options");
756 menu->SetReturnEvent(
this,
"iconimportopt");
758 menu->AddButton(tr(
"Download all icons..."));
759 menu->AddButton(tr(
"Rescan for missing icons..."));
760 if (!channelname.isEmpty())
761 menu->AddButtonV(tr(
"Download icon for %1").arg(channelname),
779 QString resultid= dce->GetId();
780 int buttonnum = dce->GetResult();
782 if (resultid ==
"channelopts")
794 else if (resultid ==
"delsingle" && buttonnum == 1)
803 else if (resultid ==
"delall" && buttonnum == 1)
811 query.
prepare(
"TRUNCATE TABLE channel");
815 query.
prepare(
"SELECT sourceid "
817 "GROUP BY sourceid");
827 tmp +=
"'" + query.
value(0).toString() +
"',";
831 query.
prepare(
"TRUNCATE TABLE channel");
836 query.
prepare(QString(
"UPDATE channel "
837 "SET deleted = NOW() "
838 "WHERE deleted IS NULL AND "
839 " sourceid NOT IN (%1)").arg(
tmp));
844 query.
prepare(
"UPDATE channel "
845 "SET deleted = NOW() "
846 "WHERE deleted IS NULL AND sourceid = :SOURCEID");
855 else if (resultid ==
"iconimportopt")
861 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)
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.