diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am index 024adfcfc..28076ef7d 100644 --- a/data/icons/Makefile.am +++ b/data/icons/Makefile.am @@ -57,6 +57,7 @@ install_DATA += \ ca.png \ ca2.png \ ca2_gray.png \ + checkmark.png \ colors.png \ conax_green.png \ conax_white.png \ diff --git a/data/icons/checkmark.png b/data/icons/checkmark.png new file mode 100755 index 000000000..59495a665 Binary files /dev/null and b/data/icons/checkmark.png differ diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 4fe597a3e..c5eeba4bf 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -818,6 +818,7 @@ menu.hint_audioplayer_title Aktivieren Sie die Titelsuche (SMS-Stil) in der Play menu.hint_auto_lang Wählen Sie, ob automatisch ihre bevorzugte Tonspur ausgewählt wird, wenn sie vorhanden ist menu.hint_auto_subs Automatische Anzeige der Untertitel in Ihrer bevorzugten Sprache menu.hint_back Zurück zum vorherigen Menü.\nDie Taste 'Menü' schließt alle Menüs +menu.hint_back_brief Zurück zum vorherigen Menü. menu.hint_backlight Konfigurieren Sie die Hintergrundbeleuchtung der Buttons menu.hint_backup Sichern von Konfigurationen und Kanallisten menu.hint_bedit Bearbeiten ihrer Favoriten und der Bouquets @@ -1034,6 +1035,8 @@ menu.hint_network IP-Adresse, Gateway, DNS, Zeit-Sync, Netzwerk-Freigaben, Diens menu.hint_new_zap_mode Aktiviert Quickzap in der Kanalliste. Nach Betätigen der Mute-Taste wird mit den Hoch/Runter-Tasten direkt umgeschalten menu.hint_numeric_adjust Adjust channel list mode on numeric zap menu.hint_onekey_plugin Wählen Sie ein Plugin, das mit einer Schnellstart-Taste gestartet wird +menu.hint_opkg Hier können Sie neue Software-Pakete installieren oder vorhandene aktualisieren +menu.hint_opkg_upgrade Aktualisiert alle installierten Pakete auf die neueste verfügbare Version menu.hint_osd Farben, Schriftarten, Anzeigegröße, Ansichtsoptionen der Menüs und mehr menu.hint_osd_language Wählen Sie ihre Menü-Sprache menu.hint_osd_preset Wählen Sie zwischen Röhren-TV (CRT) oder Flachbildschirm (LCD) @@ -1595,6 +1598,19 @@ nvod.starting (Beginn in %d min) nvodselector.directormode Bildregie-Modus nvodselector.head Anfangszeit auswählen nvodselector.subservice Perspektiven +opkg.button.expert_off Standard-Modus +opkg.button.expert_on Experten-Modus +opkg.button.info Paket-Informationen +opkg.button.install Paket installieren +opkg.button.uninstall Paket entfernen +opkg.failure.install Installation fehlgeschlagen (%d) +opkg.failure.update Update fehlgeschlagen (%d) +opkg.failure.upgrade Upgrade fehlgeschlagen (%d) +opkg.messagebox.reinstall %s erneut installieren? +opkg.messagebox.remove %s entfernen? +opkg.success.install Installation erfolgreich, Neustart von Neutrino kann erforderlich sein. +opkg.title Paketverwaltung +opkg.upgrade Installierte Pakete aktualisieren options.default Voreinstellungen benutzen options.fb framebuffer options.ntp_off DVB diff --git a/data/locale/english.locale b/data/locale/english.locale index 4e2f99b34..55c98d8ec 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -818,6 +818,7 @@ menu.hint_audioplayer_title Enable SMS-style title search in playlist menu.hint_auto_lang Auto-switch audio to preferred language menu.hint_auto_subs Auto-start subtitles for preferred language menu.hint_back Return to previous menu\nPress menu key to close all menus +menu.hint_back_brief Return to previous menu menu.hint_backlight Configure buttons backlight menu.hint_backup Backup configs and channels to selected dir menu.hint_bedit Edit favorites and bouquets @@ -1034,6 +1035,8 @@ menu.hint_network IP address, gateway, DNS, Time sync\nNetwork shares and servic menu.hint_new_zap_mode Allow channel switch while browsing\n(toggle mode with 'mute' in channel list) menu.hint_numeric_adjust Adjust channel list mode on numeric zap menu.hint_onekey_plugin Choose a plugin that's executed with the one touch key +menu.hint_opkg Install or update software packages +menu.hint_opkg_upgrade Updates all installed packages to the most recent version available menu.hint_osd Colors, fonts, screen size\nGUI look and feel options menu.hint_osd_language Select OSD language menu.hint_osd_preset Pre-configured screen margins for CRT and LCD TV @@ -1595,6 +1598,19 @@ nvod.starting (starting in %d min) nvodselector.directormode Direct-Mode nvodselector.head Select starting-time nvodselector.subservice Select Subservice +opkg.button.expert_off Standard mode +opkg.button.expert_on Expert mode +opkg.button.info Package information +opkg.button.install Install package +opkg.button.uninstall Uninstall package +opkg.failure.install Install failed (%d) +opkg.failure.update Update failed (%d) +opkg.failure.upgrade Upgrade failed (%d) +opkg.messagebox.reinstall Re-install %s? +opkg.messagebox.remove Remove %s? +opkg.success.install Install successful, restart of Neutrino might be required. +opkg.title Package Management +opkg.upgrade Upgrade installed packages options.default Reset to defaults options.fb framebuffer options.ntp_off DVB diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index e681ead81..113cadcec 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -81,6 +81,7 @@ libneutrino_gui_a_SOURCES = \ network_service.cpp \ network_setup.cpp \ nfs.cpp \ + opkg_manager.cpp \ osd_progressbar_setup.cpp \ osd_setup.cpp \ osdlang_setup.cpp \ diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp new file mode 100644 index 000000000..7bac91044 --- /dev/null +++ b/src/gui/opkg_manager.cpp @@ -0,0 +1,380 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + OPKG-Manager Class for Neutrino-GUI + + Implementation: + Copyright (C) 2012 T. Graf 'dbt' + www.dbox2-tuning.net + + Adaptions: + Copyright (C) 2013 martii + gitorious.org/neutrino-mp/martiis-neutrino-mp + + License: GPL + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define OPKG_CL find_executable("opkg-cl") +#define OPKG_KEY find_executable("opkg-key") + +enum +{ + OM_LIST, + OM_LIST_INSTALLED, + OM_LIST_UPGRADEABLE, + OM_UPDATE, + OM_UPGRADE, + OM_REMOVE, + OM_INFO, + OM_INSTALL, + OM_MAX +}; + +static const std::string pkg_types[OM_MAX] = +{ + OPKG_CL + " list", + OPKG_CL + " list-installed", + OPKG_CL + " list-upgradable", + OPKG_CL + " update", + OPKG_CL + " upgrade ", + OPKG_CL + " remove ", + OPKG_CL + " info ", + OPKG_CL + " install " +}; + +COPKGManager::COPKGManager() +{ + width = w_max (40, 10); //% + frameBuffer = CFrameBuffer::getInstance(); + pkg_map.clear(); + list_installed_done = false; + list_upgradeable_done = false; + expert_mode = false; +} + +COPKGManager::~COPKGManager() +{ +} + +int COPKGManager::exec(CMenuTarget* parent, const std::string &actionKey) +{ + int res = menu_return::RETURN_REPAINT; + + if (actionKey == "") { + if (parent) + parent->hide(); + return showMenu(); + } + int selected = menu->getSelected() - menu_offset; + + if (expert_mode && actionKey == "rc_blue") { + if (selected < 0 || selected >= (int) pkg_vec.size() || !pkg_vec[selected]->installed) + return menu_return::RETURN_NONE; + + char loc[200]; + snprintf(loc, sizeof(loc), g_Locale->getText(LOCALE_OPKG_MESSAGEBOX_REMOVE), pkg_vec[selected]->name.c_str()); + if (ShowMsg(LOCALE_OPKG_TITLE, loc, CMessageBox::mbrCancel, CMessageBox::mbYes | CMessageBox::mbCancel) != CMessageBox::mbrCancel) { + if (parent) + parent->hide(); + execCmd(pkg_types[OM_REMOVE] + pkg_vec[selected]->name, true, true); + refreshMenu(); + } + return res; + } + if (actionKey == "rc_info") { + if (selected < 0 || selected >= (int) pkg_vec.size()) + return menu_return::RETURN_NONE; + if (parent) + parent->hide(); + execCmd(pkg_types[OM_INFO] + pkg_vec[selected]->name, true, true); + return res; + } + if (actionKey == "rc_red") { + expert_mode = !expert_mode; + updateMenu(); + return res; + } + if(actionKey == pkg_types[OM_UPGRADE]) { + if (parent) + parent->hide(); + int r = execCmd(actionKey, true, true); + if (r) { + std::string loc = g_Locale->getText(LOCALE_OPKG_FAILURE_UPGRADE); + char rs[strlen(loc.c_str()) + 20]; + snprintf(rs, sizeof(rs), loc.c_str(), r); + DisplayInfoMessage(rs); + } else + installed = true; + refreshMenu(); + g_RCInput->postMsg((neutrino_msg_t) CRCInput::RC_up, 0); + return res; + } + + std::map::iterator it = pkg_map.find(actionKey); + if (it != pkg_map.end()) { + if (parent) + parent->hide(); + std::string force = ""; + if (it->second.installed && !it->second.upgradable) { + char l[200]; + snprintf(l, sizeof(l), g_Locale->getText(LOCALE_OPKG_MESSAGEBOX_REINSTALL), actionKey.c_str()); + l[sizeof(l) - 1] = 0; + if (ShowMsg(LOCALE_OPKG_TITLE, l, CMessageBox::mbrCancel, CMessageBox::mbYes | CMessageBox::mbCancel) == CMessageBox::mbrCancel) + return res; + force = "--force-reinstall "; + } + int r = execCmd(pkg_types[OM_INSTALL] + force + actionKey, true, true); + if (r) { + std::string err = g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL); + char rs[strlen(err.c_str()) + 20]; + snprintf(rs, sizeof(rs), err.c_str(), r); + DisplayInfoMessage(rs); + } else + installed = true; + refreshMenu(); + } + return res; +} + +#define COPKGManagerFooterButtonCount 3 +static const struct button_label COPKGManagerFooterButtons[COPKGManagerFooterButtonCount] = { + { NEUTRINO_ICON_BUTTON_RED, LOCALE_OPKG_BUTTON_EXPERT_ON }, + { NEUTRINO_ICON_BUTTON_INFO_SMALL, LOCALE_OPKG_BUTTON_INFO }, + { NEUTRINO_ICON_BUTTON_OKAY, LOCALE_OPKG_BUTTON_INSTALL } +}; +#define COPKGManagerFooterButtonCountExpert 4 +static const struct button_label COPKGManagerFooterButtonsExpert[COPKGManagerFooterButtonCountExpert] = { + { NEUTRINO_ICON_BUTTON_RED, LOCALE_OPKG_BUTTON_EXPERT_OFF }, + { NEUTRINO_ICON_BUTTON_INFO_SMALL, LOCALE_OPKG_BUTTON_INFO }, + { NEUTRINO_ICON_BUTTON_OKAY, LOCALE_OPKG_BUTTON_INSTALL }, + { NEUTRINO_ICON_BUTTON_BLUE, LOCALE_OPKG_BUTTON_UNINSTALL } +}; + +void COPKGManager::updateMenu() +{ + bool upgradesAvailable = false; + getPkgData(OM_LIST_INSTALLED); + getPkgData(OM_LIST_UPGRADEABLE); + for (std::map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) { + it->second.forwarder->iconName_Info_right = ""; + it->second.forwarder->setActive(true); + if (it->second.upgradable) { + it->second.forwarder->iconName_Info_right = NEUTRINO_ICON_WARNING; + upgradesAvailable = true; + } else if (it->second.installed) { + it->second.forwarder->iconName_Info_right = NEUTRINO_ICON_CHECKMARK; + it->second.forwarder->setActive(expert_mode); + } + } + + upgrade_forwarder->setActive(upgradesAvailable); + + if (expert_mode) + menu->setFooter(COPKGManagerFooterButtonsExpert, COPKGManagerFooterButtonCountExpert); + else + menu->setFooter(COPKGManagerFooterButtons, COPKGManagerFooterButtonCount); +} + +void COPKGManager::refreshMenu() { + list_installed_done = false, + list_upgradeable_done = false; + updateMenu(); +} + +int COPKGManager::showMenu() +{ + installed = false; + + int r = execCmd(pkg_types[OM_UPDATE]); + if (r) { + std::string loc = g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE); + char rs[strlen(loc.c_str()) + 20]; + snprintf(rs, sizeof(rs), loc.c_str(), r); + DisplayInfoMessage(rs); + } + + getPkgData(OM_LIST); + getPkgData(OM_LIST_UPGRADEABLE); + + menu = new CMenuWidget(g_Locale->getText(LOCALE_OPKG_TITLE), NEUTRINO_ICON_UPDATE, width, MN_WIDGET_ID_SOFTWAREUPDATE); + CMenuForwarder menuBack(LOCALE_MENU_BACK, true, NULL, NULL, NULL, CRCInput::RC_nokey, NEUTRINO_ICON_BUTTON_LEFT, NULL, true); + menuBack.setItemButton(!g_settings.menu_left_exit ? NEUTRINO_ICON_BUTTON_HOME : NEUTRINO_ICON_BUTTON_LEFT); + menu->addItem(&menuBack); + menuBack.setHint(NEUTRINO_ICON_HINT_BACK, LOCALE_MENU_HINT_BACK_BRIEF); + menu->addItem(GenericMenuSeparatorLine); + + upgrade_forwarder = new CMenuForwarder(LOCALE_OPKG_UPGRADE, true, NULL , this, pkg_types[OM_UPGRADE].c_str(), CRCInput::RC_red); + upgrade_forwarder->setHint(NEUTRINO_ICON_HINT_SW_UPDATE, LOCALE_MENU_HINT_OPKG_UPGRADE); + menu->addItem(upgrade_forwarder); + menu->addItem(GenericMenuSeparatorLine); + + menu_offset = menu->getItemsCount(); + + menu->addKey(CRCInput::RC_info, this, "rc_info"); + menu->addKey(CRCInput::RC_blue, this, "rc_blue"); + menu->addKey(CRCInput::RC_red, this, "rc_red"); + + pkg_vec.clear(); + for (std::map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) { + it->second.forwarder = new CMenuForwarder(it->second.desc, true, NULL , this, it->second.name.c_str()); + it->second.forwarder->setHint("", it->second.desc); + menu->addItem(it->second.forwarder); + pkg_vec.push_back(&it->second); + } + + updateMenu(); + + int res = menu->exec(NULL, ""); + + menu->hide (); + + if (installed) + DisplayInfoMessage(g_Locale->getText(LOCALE_OPKG_SUCCESS_INSTALL)); + delete menu; + return res; +} + +bool COPKGManager::hasOpkgSupport() +{ + string deps[] = {OPKG_CL, OPKG_KEY, "/etc/opkg/opkg.conf", "/var/lib/opkg"}; + + for(size_t i=0; i::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) + it->second.installed = false; + break; + case OM_LIST_UPGRADEABLE: + if (list_upgradeable_done) + return; + list_upgradeable_done = true; + for (std::map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) + it->second.upgradable = false; + break; + } + + FILE *f = popen(pkg_types[pkg_content_id].c_str(), "r"); + if (!f) { + DisplayInfoMessage("Command failed"); + return; + } + + char buf[256]; + + while (fgets(buf, sizeof(buf), f)) + { + std::string line(buf); + trim(line); + + std::string name = getBlankPkgName(line); + + switch (pkg_content_id) { + case OM_LIST: { + pkg_map[name] = pkg(name, line); + break; + } + case OM_LIST_INSTALLED: { + std::map::iterator it = pkg_map.find(name); + if (it != pkg_map.end()) + it->second.installed = true; + break; + } + case OM_LIST_UPGRADEABLE: { + std::map::iterator it = pkg_map.find(name); + if (it != pkg_map.end()) + it->second.upgradable = true; + break; + } + default: + fprintf(stderr, "%s %s %d: unrecognized content id %d\n", __FILE__, __func__, __LINE__, pkg_content_id); + break; + } + } + + pclose(f); +} + +std::string COPKGManager::getBlankPkgName(const std::string& line) +{ + size_t l_pos = line.find(" "); + if (l_pos != string::npos) + return line.substr(0, l_pos); + return line; +} + +int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) +{ +fprintf(stderr, "execCmd(%s)\n", cmdstr); + std::string cmd(cmdstr); + if (verbose) { + cmd += " 2>&1"; + int res; + CShellWindow(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE : 0), &res); + return res; + } else { + cmd += " 2>/dev/null >&2"; + int r = system(cmd.c_str()); + if (r == -1) + return r; + return WEXITSTATUS(r); + } +} diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h new file mode 100644 index 000000000..26e89afcb --- /dev/null +++ b/src/gui/opkg_manager.h @@ -0,0 +1,88 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + OPKG-Manager Class for Neutrino-GUI + + Implementation: + Copyright (C) 2012 T. Graf 'dbt' + www.dbox2-tuning.net + + Adaptions: + Copyright (C) 2013 martii + gitorious.org/neutrino-mp/martiis-neutrino-mp + + License: GPL + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __OPKG_MANAGER__ +#define __OPKG_MANAGER__ + +#include +#include + +#include +#include +#include + +class COPKGManager : public CMenuTarget +{ + private: + int width; + + CFrameBuffer *frameBuffer; + + struct pkg; + + std::map pkg_map; + std::vector pkg_vec; + + CMenuWidget *menu; + CMenuForwarder *upgrade_forwarder; + bool list_installed_done; + bool list_upgradeable_done; + bool installed; + bool expert_mode; + int menu_offset; + + int execCmd(const char* cmdstr, bool verbose = false, bool acknowledge = false); + int execCmd(std::string cmdstr, bool verbose = false, bool acknowledge = false) { + return execCmd(cmdstr.c_str(), verbose, acknowledge); + }; + void getPkgData(const int pkg_content_id); + static std::string getBlankPkgName(const std::string& line); + int showMenu(); + void updateMenu(); + void refreshMenu(); + + struct pkg { + std::string name; + std::string desc; + bool installed; + bool upgradable; + CMenuForwarder *forwarder; + pkg() { } + pkg(std::string &_name, std::string &_desc) + : name(_name), desc(_desc), installed(false), upgradable(false) { } + }; + public: + COPKGManager(); + ~COPKGManager(); + + int exec(CMenuTarget* parent, const std::string & actionKey); + static bool hasOpkgSupport(); +}; +#endif diff --git a/src/gui/update_menue.cpp b/src/gui/update_menue.cpp index 5cfd1830c..824305e7c 100644 --- a/src/gui/update_menue.cpp +++ b/src/gui/update_menue.cpp @@ -41,7 +41,7 @@ #include "update_menue.h" #include "update_settings.h" - +#include "gui/opkg_manager.h" #include #include #include @@ -113,7 +113,15 @@ int CSoftwareUpdate::showSoftwareUpdate() mf->setHint("", LOCALE_MENU_HINT_SOFTUPDATE_EXPERT); softUpdate.addItem(mf); + //firmware update via opkg + if (COPKGManager::hasOpkgSupport()) { + mf = new CMenuForwarder(LOCALE_OPKG_TITLE, true, NULL, new COPKGManager()); + mf->setHint(NEUTRINO_ICON_HINT_SW_UPDATE, LOCALE_MENU_HINT_OPKG); + softUpdate.addItem(mf); + } + } + #ifdef BOXMODEL_APOLLO softUpdate.addItem(GenericMenuSeparatorLine); diff --git a/src/gui/widget/Makefile.am b/src/gui/widget/Makefile.am index d119ced33..3040302e1 100644 --- a/src/gui/widget/Makefile.am +++ b/src/gui/widget/Makefile.am @@ -38,6 +38,7 @@ libneutrino_gui_widget_a_SOURCES = \ messagebox.cpp \ mountchooser.cpp \ msgbox.cpp \ + shellwindow.cpp \ stringinput.cpp \ stringinput_ext.cpp \ textbox.cpp diff --git a/src/gui/widget/icons.h b/src/gui/widget/icons.h index a58b95393..1f7115bf6 100644 --- a/src/gui/widget/icons.h +++ b/src/gui/widget/icons.h @@ -248,6 +248,10 @@ #define NEUTRINO_ICON_HINT_RESTORE "hint_restore" #define NEUTRINO_ICON_HINT_FACTORY "hint_factory" +/* opkg manager */ +#define NEUTRINO_ICON_CHECKMARK "checkmark" +#define NEUTRINO_ICON_WARNING "warning" + /* misc */ #define NEUTRINO_ICON_HINT_YTPLAY "hint_ytplay" diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp new file mode 100644 index 000000000..46a9e43ec --- /dev/null +++ b/src/gui/widget/shellwindow.cpp @@ -0,0 +1,205 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Shell window class, visualize of system events on gui screen. + + Implementation: + Copyright (C) 2013 martii + gitorious.org/neutrino-mp/martiis-neutrino-mp + + License: GPL + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + + +#include "shellwindow.h" + +#include +#include +#include +#include +#include +#include +#include + +CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res) { + textBox = NULL; + std::string cmd; + mode = _mode; + if (!(mode & VERBOSE)){ + cmd = "PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin ; export PATH ; " + command + " 2>/dev/null >&2"; + int r = system(cmd.c_str()); + if (res) { + if (r == -1) + *res = r; + else + *res = WEXITSTATUS(r); + } + return; + } + + cmd = command + " 2>&1"; + FILE *f = popen(cmd.c_str(), "r"); + if (!f) { + if (res) + *res = -1; + return; + } + Font *font = g_Font[SNeutrinoSettings::FONT_TYPE_GAMELIST_ITEMSMALL]; + frameBuffer = CFrameBuffer::getInstance(); + unsigned int lines_max = frameBuffer->getScreenHeight() / font->getHeight(); + list lines; + CBox textBoxPosition(frameBuffer->getScreenX(), frameBuffer->getScreenY(), frameBuffer->getScreenWidth(), frameBuffer->getScreenHeight()); + textBox = new CTextBox(cmd.c_str(), font, CTextBox::BOTTOM, &textBoxPosition); + struct pollfd fds; + fds.fd = fileno(f); + fds.events = POLLIN | POLLHUP | POLLERR; + fcntl(fds.fd, F_SETFL, fcntl(fds.fd, F_GETFL, 0) | O_NONBLOCK); + + struct timeval tv; + gettimeofday(&tv,NULL); + uint64_t lastPaint = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); + bool ok = true, nlseen = false, dirty = false, pushed = false; + char output[1024]; + int off = 0; + std::string txt = ""; + + do { + uint64_t now; + fds.revents = 0; + int r = poll(&fds, 1, 300); + + if (r > 0) { + if (!feof(f)) { + gettimeofday(&tv,NULL); + now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); + + unsigned int lines_read = 0; + while (fgets(output + off, sizeof(output) - off, f)) { + char *outputp = output + off; + dirty = true; + + for (int i = off; output[i] && !nlseen; i++) + switch (output[i]) { + case '\b': + if (outputp > output) + outputp--; + *outputp = 0; + break; + case '\r': + outputp = output; + break; + case '\n': + lines_read++; + nlseen = true; + *outputp = 0; + break; + default: + *outputp++ = output[i]; + break; + } + + if (outputp < output + sizeof(output)) + *outputp = 0; + if (nlseen) { + pushed = false; + nlseen = false; + off = 0; + } else { + off = strlen(output); + if (pushed) + lines.pop_back(); + } + lines.push_back(std::string((output))); + pushed = true; + if (lines.size() > lines_max) + lines.pop_front(); + txt = ""; + bool first = true; + for (std::list::const_iterator it = lines.begin(), end = lines.end(); it != end; ++it) { + if (first) + first = false; + else + txt += '\n'; + txt += *it; + } + if (((lines_read == lines_max) && (lastPaint + 100000 < now)) || (lastPaint + 250000 < now)) { + textBox->setText(&txt); + textBox->paint(); + lines_read = 0; + lastPaint = now; + dirty = false; + } + } + } else + ok = false; + } else if (r < 0) + ok = false; + + gettimeofday(&tv,NULL); + now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); + if (r < 1 || dirty || lastPaint + 250000 < now) { + textBox->setText(&txt); + textBox->paint(); + lastPaint = now; + dirty = false; + } + } while(ok); + + int r = pclose(f); + + if (res) { + if (r == -1) + *res = r; + else + *res = WEXITSTATUS(r); + } +} + +CShellWindow::~CShellWindow() +{ + if (textBox && (mode & ACKNOWLEDGE)) { + int iw, ih; + frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_OKAY, &iw, &ih); + Font *font = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]; + int b_width = font->getRenderWidth(g_Locale->getText(LOCALE_MESSAGEBOX_OK), true) + 36 + ih + (RADIUS_LARGE / 2); + int fh = font->getHeight(); + int b_height = std::max(fh, ih) + 8 + (RADIUS_LARGE / 2); + int xpos = frameBuffer->getScreenWidth() - b_width; + int ypos = frameBuffer->getScreenHeight() - b_height; + frameBuffer->paintBoxRel(xpos, ypos, b_width, b_height, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE); + frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_OKAY, xpos + ((b_height - ih) / 2), ypos + ((b_height - ih) / 2), ih); + font->RenderString(xpos + iw + 17, ypos + fh + ((b_height - fh) / 2), b_width - (iw + 21), g_Locale->getText(LOCALE_MESSAGEBOX_OK), COL_MENUCONTENT_TEXT, 0, true); + frameBuffer->blit(); + + neutrino_msg_t msg; + neutrino_msg_data_t data; + do + g_RCInput->getMsg(&msg, &data, 100); + while (msg != CRCInput::RC_ok && msg != CRCInput::RC_home); + + frameBuffer->Clear(); + frameBuffer->blit(); + } + if (textBox) { + textBox->hide(); + delete textBox; + } +} diff --git a/src/gui/widget/shellwindow.h b/src/gui/widget/shellwindow.h new file mode 100644 index 000000000..a7c05b7fd --- /dev/null +++ b/src/gui/widget/shellwindow.h @@ -0,0 +1,48 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Shell window class, visualize of system events on gui screen. + + Implementation: + Copyright (C) 2013 martii + gitorious.org/neutrino-mp/martiis-neutrino-mp + + License: GPL + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __WIDGET_SHELLWINDOW_H__ +#define __WIDGET_SHELLWINDOW_H__ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +class CShellWindow +{ + public: + enum shellwindow_modes { VERBOSE = 1, ACKNOWLEDGE = 2 }; + CShellWindow(const std::string &cmd, const int mode = 0, int *res = NULL); + ~CShellWindow(); + private: + int mode; + CFrameBuffer *frameBuffer; + CTextBox *textBox; +}; + +#endif diff --git a/src/neutrino_menue.cpp b/src/neutrino_menue.cpp index b6461901b..86e2ba133 100644 --- a/src/neutrino_menue.cpp +++ b/src/neutrino_menue.cpp @@ -513,6 +513,9 @@ void CNeutrinoApp::InitMenuService() } //separator + personalize.addSeparator(MENU_SERVICE); + + if (!g_settings.easymenu) { personalize.addSeparator(MENU_SERVICE); diff --git a/src/system/locals.h b/src/system/locals.h index 6705a008d..5b07e212e 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -845,6 +845,7 @@ typedef enum LOCALE_MENU_HINT_AUTO_LANG, LOCALE_MENU_HINT_AUTO_SUBS, LOCALE_MENU_HINT_BACK, + LOCALE_MENU_HINT_BACK_BRIEF, LOCALE_MENU_HINT_BACKLIGHT, LOCALE_MENU_HINT_BACKUP, LOCALE_MENU_HINT_BEDIT, @@ -1061,6 +1062,8 @@ typedef enum LOCALE_MENU_HINT_NEW_ZAP_MODE, LOCALE_MENU_HINT_NUMERIC_ADJUST, LOCALE_MENU_HINT_ONEKEY_PLUGIN, + LOCALE_MENU_HINT_OPKG, + LOCALE_MENU_HINT_OPKG_UPGRADE, LOCALE_MENU_HINT_OSD, LOCALE_MENU_HINT_OSD_LANGUAGE, LOCALE_MENU_HINT_OSD_PRESET, @@ -1622,6 +1625,19 @@ typedef enum LOCALE_NVODSELECTOR_DIRECTORMODE, LOCALE_NVODSELECTOR_HEAD, LOCALE_NVODSELECTOR_SUBSERVICE, + LOCALE_OPKG_BUTTON_EXPERT_OFF, + LOCALE_OPKG_BUTTON_EXPERT_ON, + LOCALE_OPKG_BUTTON_INFO, + LOCALE_OPKG_BUTTON_INSTALL, + LOCALE_OPKG_BUTTON_UNINSTALL, + LOCALE_OPKG_FAILURE_INSTALL, + LOCALE_OPKG_FAILURE_UPDATE, + LOCALE_OPKG_FAILURE_UPGRADE, + LOCALE_OPKG_MESSAGEBOX_REINSTALL, + LOCALE_OPKG_MESSAGEBOX_REMOVE, + LOCALE_OPKG_SUCCESS_INSTALL, + LOCALE_OPKG_TITLE, + LOCALE_OPKG_UPGRADE, LOCALE_OPTIONS_DEFAULT, LOCALE_OPTIONS_FB, LOCALE_OPTIONS_NTP_OFF, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index 5a03fee7e..4f79e8204 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -845,6 +845,7 @@ const char * locale_real_names[] = "menu.hint_auto_lang", "menu.hint_auto_subs", "menu.hint_back", + "menu.hint_back_brief", "menu.hint_backlight", "menu.hint_backup", "menu.hint_bedit", @@ -1061,6 +1062,8 @@ const char * locale_real_names[] = "menu.hint_new_zap_mode", "menu.hint_numeric_adjust", "menu.hint_onekey_plugin", + "menu.hint_opkg", + "menu.hint_opkg_upgrade", "menu.hint_osd", "menu.hint_osd_language", "menu.hint_osd_preset", @@ -1622,6 +1625,19 @@ const char * locale_real_names[] = "nvodselector.directormode", "nvodselector.head", "nvodselector.subservice", + "opkg.button.expert_off", + "opkg.button.expert_on", + "opkg.button.info", + "opkg.button.install", + "opkg.button.uninstall", + "opkg.failure.install", + "opkg.failure.update", + "opkg.failure.upgrade", + "opkg.messagebox.reinstall", + "opkg.messagebox.remove", + "opkg.success.install", + "opkg.title", + "opkg.upgrade", "options.default", "options.fb", "options.ntp_off",