Esempio n. 1
0
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();
	}

}
Esempio n. 2
0
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;
	}