void formaction::start_bookmark_qna(const std::string& default_title, const std::string& default_url, const std::string& default_desc) { LOG(LOG_DEBUG, "formaction::start_bookmark_qna: starting bookmark Q&A... default_title = %s default_url = %s default_desc = %s", default_title.c_str(), default_url.c_str(), default_desc.c_str()); std::vector<qna_pair> prompts; prompts.push_back(qna_pair(_("URL: "), default_url)); prompts.push_back(qna_pair(_("Title: "), default_title)); prompts.push_back(qna_pair(_("Description: "), default_desc)); start_qna(prompts, OP_INT_BM_END); }
void itemview_formaction::process_operation(operation op, bool automatic, std::vector<std::string> * args) { std::shared_ptr<rss_item> item = feed->get_item_by_guid(guid); bool hardquit = false; /* * whenever we process an operation, we mark the item * as read. Don't worry: when an item is already marked as * read, and then marked as read again, no database update * is done, since only _changes_ to the unread flag are * recorded in the database. */ try { bool old_unread = item->unread(); item->set_unread(false); if (old_unread) { v->get_ctrl()->mark_article_read(item->guid(), true); } } catch (const dbexception& e) { v->show_error(utils::strprintf(_("Error while marking article as read: %s"), e.what())); } switch (op) { case OP_TOGGLESOURCEVIEW: LOG(LOG_INFO, "view::run_itemview: toggling source view"); show_source = !show_source; do_redraw = true; break; case OP_ENQUEUE: { if (item->enclosure_url().length() > 0 && utils::is_http_url(item->enclosure_url())) { v->get_ctrl()->enqueue_url(item->enclosure_url(), feed); v->set_status(utils::strprintf(_("Added %s to download queue."), item->enclosure_url().c_str())); } else { v->set_status(utils::strprintf(_("Invalid URL: '%s'"), item->enclosure_url().c_str())); } } break; case OP_SAVE: { LOG(LOG_INFO, "view::run_itemview: saving article"); std::string filename; if (automatic) { if (args->size() > 0) filename = (*args)[0]; } else { filename = v->run_filebrowser(v->get_filename_suggestion(item->title())); } if (filename == "") { v->show_error(_("Aborted saving.")); } else { try { v->get_ctrl()->write_item(item, filename); v->show_error(utils::strprintf(_("Saved article to %s."), filename.c_str())); } catch (...) { v->show_error(utils::strprintf(_("Error: couldn't write article to file %s"), filename.c_str())); } } } break; case OP_OPENINBROWSER: LOG(LOG_INFO, "view::run_itemview: starting browser"); v->set_status(_("Starting browser...")); v->open_in_browser(item->link()); v->set_status(""); break; case OP_BOOKMARK: if (automatic) { qna_responses.clear(); qna_responses.push_back(item->link()); qna_responses.push_back(item->title()); qna_responses.push_back(args->size() > 0 ? (*args)[0] : ""); } else { this->start_bookmark_qna(item->title(), item->link(), ""); } break; case OP_SEARCH: { std::vector<qna_pair> qna; if (automatic) { if (args->size() > 0) { qna_responses.clear(); qna_responses.push_back((*args)[0]); finished_qna(OP_INT_START_SEARCH); } } else { qna.push_back(qna_pair(_("Search for: "), "")); this->start_qna(qna, OP_INT_START_SEARCH, &searchhistory); } } break; case OP_PIPE_TO: { std::vector<qna_pair> qna; if (automatic) { if (args->size() > 0) { qna_responses.clear(); qna_responses.push_back((*args)[0]); finished_qna(OP_PIPE_TO); } } else { qna.push_back(qna_pair(_("Pipe article to command: "), "")); this->start_qna(qna, OP_PIPE_TO, &cmdlinehistory); } } break; case OP_EDITFLAGS: if (automatic) { qna_responses.clear(); if (args->size() > 0) { qna_responses.push_back((*args)[0]); this->finished_qna(OP_INT_EDITFLAGS_END); } } else { std::vector<qna_pair> qna; qna.push_back(qna_pair(_("Flags: "), item->flags())); this->start_qna(qna, OP_INT_EDITFLAGS_END); } break; case OP_SHOWURLS: { std::string urlviewer = v->get_cfg()->get_configvalue("external-url-viewer"); LOG(LOG_DEBUG, "view::run_itemview: showing URLs"); if (urlviewer == "") { if (links.size() > 0) { v->push_urlview(links); } else { v->show_error(_("URL list empty.")); } } else { qna_responses.clear(); qna_responses.push_back(urlviewer); this->finished_qna(OP_PIPE_TO); } } break; case OP_DELETE: LOG(LOG_INFO, "view::run_itemview: deleting current article"); item->set_deleted(true); v->get_ctrl()->mark_deleted(guid, true); /* fall-through! */ case OP_NEXTUNREAD: LOG(LOG_INFO, "view::run_itemview: jumping to next unread article"); if (v->get_next_unread(itemlist.get(), this)) { do_redraw = true; } else { v->pop_current_formaction(); v->show_error(_("No unread items.")); } break; case OP_PREVUNREAD: LOG(LOG_INFO, "view::run_itemview: jumping to previous unread article"); if (v->get_previous_unread(itemlist.get(), this)) { do_redraw = true; } else { v->pop_current_formaction(); v->show_error(_("No unread items.")); } break; case OP_NEXT: LOG(LOG_INFO, "view::run_itemview: jumping to next article"); if (v->get_next(itemlist.get(), this)) { do_redraw = true; } else { v->pop_current_formaction(); v->show_error(_("Already on last item.")); } break; case OP_PREV: LOG(LOG_INFO, "view::run_itemview: jumping to previous article"); if (v->get_previous(itemlist.get(), this)) { do_redraw = true; } else { v->pop_current_formaction(); v->show_error(_("Already on first item.")); } break; case OP_RANDOMUNREAD: LOG(LOG_INFO, "view::run_itemview: jumping to random unread article"); if (v->get_random_unread(itemlist.get(), this)) { do_redraw = true; } else { v->pop_current_formaction(); v->show_error(_("No unread items.")); } break; case OP_TOGGLEITEMREAD: LOG(LOG_INFO, "view::run_itemview: setting unread and quitting"); v->set_status(_("Toggling read flag for article...")); try { item->set_unread(true); v->get_ctrl()->mark_article_read(item->guid(), false); } catch (const dbexception& e) { v->show_error(utils::strprintf(_("Error while marking article as unread: %s"), e.what())); } v->set_status(""); quit = true; break; case OP_QUIT: LOG(LOG_INFO, "view::run_itemview: quitting"); quit = true; break; case OP_HARDQUIT: LOG(LOG_INFO, "view::run_itemview: hard quitting"); hardquit = true; break; case OP_HELP: v->push_help(); break; case OP_1: case OP_2: case OP_3: case OP_4: case OP_5: case OP_6: case OP_7: case OP_8: case OP_9: case OP_0: { unsigned int idx = op - OP_1; LOG(LOG_DEBUG, "itemview::run: OP_1 = %d op = %d idx = %u", OP_1, op, idx); if(idx < links.size()) { v->set_status(_("Starting browser...")); v->open_in_browser(links[idx].first); v->set_status(""); } } break; case OP_GOTO_URL: { std::vector<qna_pair> qna; if (automatic) { if (args->size() > 0) { qna_responses.clear(); qna_responses.push_back((*args)[0]); finished_qna(OP_INT_GOTO_URL); } } else { qna.push_back(qna_pair(_("Goto URL #"), "")); this->start_qna(qna, OP_INT_GOTO_URL); } } break; default: break; } if (hardquit) { while (v->formaction_stack_size() > 0) { v->pop_current_formaction(); } } else if (quit) { v->pop_current_formaction(); } }
void feedlist_formaction::process_operation(operation op, bool automatic, std::vector<std::string> * args) { std::string feedpos = f->get("feedposname"); std::istringstream posname(feedpos); unsigned int pos = 0; posname >> pos; switch (op) { case OP_OPEN: { if (f->get_focus() == "feeds") { if (automatic && args->size() > 0) { std::istringstream x((*args)[0]); x >> pos; } LOG(LOG_INFO, "feedlist_formaction: opening feed at position `%s'",feedpos.c_str()); if (feeds_shown > 0 && feedpos.length() > 0) { v->push_itemlist(pos); } else { v->show_error(_("No feed selected!")); // should not happen } } } break; case OP_RELOAD: { LOG(LOG_INFO, "feedlist_formaction: reloading feed at position `%s'",feedpos.c_str()); if (feeds_shown > 0 && feedpos.length() > 0) { v->get_ctrl()->reload(pos); } else { v->show_error(_("No feed selected!")); // should not happen } } break; case OP_INT_RESIZE: do_redraw = true; break; case OP_RELOADURLS: v->get_ctrl()->reload_urls_file(); break; case OP_SORT: { char c = v->confirm(_("Sort by (f)irsttag/(t)itle/(a)rticlecount/(u)nreadarticlecount/(n)one?"), _("ftaun")); if (!c) break; std::string result(1, c); if (result == _("f")) { v->get_cfg()->set_configvalue("feed-sort-order", "firsttag-desc"); } else if (result == _("t")) { v->get_cfg()->set_configvalue("feed-sort-order", "title-desc"); } else if (result == _("a")) { v->get_cfg()->set_configvalue("feed-sort-order", "articlecount-desc"); } else if (result == _("u")) { v->get_cfg()->set_configvalue("feed-sort-order", "unreadarticlecount-desc"); } else if (result == _("n")) { v->get_cfg()->set_configvalue("feed-sort-order", "none-desc"); } } break; case OP_REVSORT: { char c = v->confirm(_("Reverse Sort by (f)irsttag/(t)itle/(a)rticlecount/(u)nreadarticlecount/(n)one?"), _("ftaun")); if (!c) break; std::string result(1, c); if (result == _("f")) { v->get_cfg()->set_configvalue("feed-sort-order", "firsttag-asc"); } else if (result == _("t")) { v->get_cfg()->set_configvalue("feed-sort-order", "title-asc"); } else if (result == _("a")) { v->get_cfg()->set_configvalue("feed-sort-order", "articlecount-asc"); } else if (result == _("u")) { v->get_cfg()->set_configvalue("feed-sort-order", "unreadarticlecount-asc"); } else if (result == _("n")) { v->get_cfg()->set_configvalue("feed-sort-order", "none-asc"); } } break; case OP_OPENINBROWSER: if (feeds_shown > 0 && feedpos.length() > 0) { std::tr1::shared_ptr<rss_feed> feed = v->get_ctrl()->get_feed(pos); if (feed) { LOG(LOG_INFO, "feedlist_formaction: opening feed at position `%s': %s", feedpos.c_str(), feed->link().c_str()); v->open_in_browser(feed->link()); } } else { v->show_error(_("No feed selected!")); } break; case OP_RELOADALL: LOG(LOG_INFO, "feedlist_formaction: reloading all feeds"); { bool reload_only_visible_feeds = v->get_cfg()->get_configvalue_as_bool("reload-only-visible-feeds"); std::vector<int> idxs; for (std::vector<feedptr_pos_pair>::iterator it=visible_feeds.begin();it!=visible_feeds.end();++it) { idxs.push_back(it->second); } v->get_ctrl()->start_reload_all_thread(reload_only_visible_feeds ? &idxs : NULL); } break; case OP_MARKFEEDREAD: { LOG(LOG_INFO, "feedlist_formaction: marking feed read at position `%s'",feedpos.c_str()); if (feeds_shown > 0 && feedpos.length() > 0) { v->set_status(_("Marking feed read...")); try { v->get_ctrl()->mark_all_read(pos); do_redraw = true; v->set_status(""); if (feeds_shown > (pos + 1) && !apply_filter) { f->set("feedpos", utils::to_string<unsigned int>(pos + 1)); } } catch (const dbexception& e) { v->show_error(utils::strprintf(_("Error: couldn't mark feed read: %s"), e.what())); } } else { v->show_error(_("No feed selected!")); // should not happen } } break; case OP_TOGGLESHOWREAD: m.parse(FILTER_UNREAD_FEEDS); LOG(LOG_INFO, "feedlist_formaction: toggling show-read-feeds"); if (v->get_cfg()->get_configvalue_as_bool("show-read-feeds")) { v->get_cfg()->set_configvalue("show-read-feeds","no"); apply_filter = true; } else { v->get_cfg()->set_configvalue("show-read-feeds","yes"); apply_filter = false; } save_filterpos(); do_redraw = true; break; case OP_NEXTUNREAD: { unsigned int local_tmp; LOG(LOG_INFO, "feedlist_formaction: jumping to next unread feed"); if (!jump_to_next_unread_feed(local_tmp)) { v->show_error(_("No feeds with unread items.")); } } break; case OP_PREVUNREAD: { unsigned int local_tmp; LOG(LOG_INFO, "feedlist_formaction: jumping to previous unread feed"); if (!jump_to_previous_unread_feed(local_tmp)) { v->show_error(_("No feeds with unread items.")); } } break; case OP_NEXT: { unsigned int local_tmp; LOG(LOG_INFO, "feedlist_formaction: jumping to next feed"); if (!jump_to_next_feed(local_tmp)) { v->show_error(_("Already on last feed.")); } } break; case OP_PREV: { unsigned int local_tmp; LOG(LOG_INFO, "feedlist_formaction: jumping to previous feed"); if (!jump_to_previous_feed(local_tmp)) { v->show_error(_("Already on first feed.")); } } break; case OP_RANDOMUNREAD: { unsigned int local_tmp; LOG(LOG_INFO, "feedlist_formaction: jumping to random unread feed"); if (!jump_to_random_unread_feed(local_tmp)) { v->show_error(_("No feeds with unread items.")); } } break; case OP_MARKALLFEEDSREAD: LOG(LOG_INFO, "feedlist_formaction: marking all feeds read"); v->set_status(_("Marking all feeds read...")); v->get_ctrl()->catchup_all(); v->set_status(""); do_redraw = true; break; case OP_CLEARTAG: tag = ""; do_redraw = true; zero_feedpos = true; break; case OP_SETTAG: if (tags.size() > 0) { std::string newtag; if (automatic && args->size() > 0) { newtag = (*args)[0]; } else { newtag = v->select_tag(tags); } if (newtag != "") { tag = newtag; do_redraw = true; zero_feedpos = true; } } else { v->show_error(_("No tags defined.")); } break; case OP_SELECTFILTER: if (v->get_ctrl()->get_filters().size() > 0) { std::string newfilter; if (automatic && args->size() > 0) { newfilter = (*args)[0]; } else { newfilter = v->select_filter(v->get_ctrl()->get_filters().get_filters()); } if (newfilter != "") { filterhistory.add_line(newfilter); if (newfilter.length() > 0) { if (!m.parse(newfilter)) { v->show_error(utils::strprintf(_("Error: couldn't parse filter command `%s': %s"), newfilter.c_str(), m.get_parse_error().c_str())); m.parse(FILTER_UNREAD_FEEDS); } else { save_filterpos(); apply_filter = true; do_redraw = true; } } } } else { v->show_error(_("No filters defined.")); } break; case OP_SEARCH: if (automatic && args->size() > 0) { qna_responses.clear(); // when in automatic mode, we manually fill the qna_responses vector from the arguments // and then run the finished_qna() by ourselves to simulate a "Q&A" session that is // in fact macro-driven. qna_responses.push_back((*args)[0]); finished_qna(OP_INT_START_SEARCH); } else { std::vector<qna_pair> qna; qna.push_back(qna_pair(_("Search for: "), "")); this->start_qna(qna, OP_INT_START_SEARCH, &searchhistory); } break; case OP_CLEARFILTER: apply_filter = !(v->get_cfg()->get_configvalue_as_bool("show-read-feeds")); m.parse(FILTER_UNREAD_FEEDS); do_redraw = true; save_filterpos(); break; case OP_SETFILTER: if (automatic && args->size() > 0) { qna_responses.clear(); qna_responses.push_back((*args)[0]); finished_qna(OP_INT_END_SETFILTER); } else { std::vector<qna_pair> qna; qna.push_back(qna_pair(_("Filter: "), "")); this->start_qna(qna, OP_INT_END_SETFILTER, &filterhistory); } break; case OP_EDIT_URLS: v->get_ctrl()->edit_urls_file(); break; case OP_QUIT: LOG(LOG_INFO, "feedlist_formaction: quitting"); if (automatic || !v->get_cfg()->get_configvalue_as_bool("confirm-exit") || v->confirm(_("Do you really want to quit (y:Yes n:No)? "), _("yn")) == *_("y")) { quit = true; } break; case OP_HARDQUIT: LOG(LOG_INFO, "feedlist_formaction: hard quitting"); quit = true; break; case OP_HELP: v->push_help(); break; default: break; }
void formaction::start_cmdline() { std::vector<qna_pair> qna; qna.push_back(qna_pair(":", "")); v->inside_cmdline(true); this->start_qna(qna, OP_INT_END_CMDLINE, &formaction::cmdlinehistory); }