void NewTabMenuManager::OpenTab (QAction *action)
	{
		QObject *pObj = action->property ("PluginObj").value<QObject*> ();
		IHaveTabs *tabs = qobject_cast<IHaveTabs*> (pObj);
		if (!tabs)
		{
			qWarning () << Q_FUNC_INFO
					<< pObj
					<< "doesn't implement IHaveTabs";
			return;
		}

		const QByteArray& tabClass = action->property ("TabClass").toByteArray ();
		tabs->TabOpenRequested (tabClass);

		const auto& classes = tabs->GetTabClasses ();
		const auto pos = std::find_if (classes.begin (), classes.end (),
				[&tabClass] (decltype (classes.front ()) item) { return item.TabClass_ == tabClass; });
		if (action->property ("Single").toBool ())
		{
			NewTabMenu_->removeAction (action);
			HiddenActions_ [pObj] [tabClass] = action;
			ToggleHide (pObj, tabClass, false);
		}
		else if (pos != classes.end () && pos->Features_ & TFByDefault)
			ToggleHide (pObj, tabClass, false);
	}
	void NewTabMenuManager::AddObject (QObject *obj)
	{
		IHaveTabs *imt = qobject_cast<IHaveTabs*> (obj);
		if (!imt || RegisteredMultiTabs_.contains (obj))
			return;

		IInfo *ii = qobject_cast<IInfo*> (obj);

		for (const auto& info : imt->GetTabClasses ())
		{
			if (!(info.Features_ & TFOpenableByRequest))
				continue;

			QAction *newAct = new QAction (info.Icon_,
					AccelerateName (info.VisibleName_),
					this);
			connect (newAct,
					SIGNAL (triggered ()),
					this,
					SLOT (handleNewTabRequested ()));
			newAct->setProperty ("PluginObj", QVariant::fromValue<QObject*> (obj));
			newAct->setProperty ("TabClass", info.TabClass_);
			newAct->setProperty ("Single",
					static_cast<bool> (info.Features_ & TFSingle));
			newAct->setStatusTip (info.Description_);
			newAct->setToolTip (info.Description_);

			InsertAction (newAct);

			if (info.Features_ & TFByDefault)
			{
				const QByteArray& id = ii->GetUniqueID () + '|' + info.TabClass_;
				const bool hide = XmlSettingsManager::Instance ()->Property ("Hide" + id, false).toBool ();
				if (!hide)
				{
					OpenTab (newAct);
					XmlSettingsManager::Instance ()->setProperty ("Hide" + id, true);
				}
			}
		}
	}
	void CoreInstanceObject::BuildNewTabModel ()
	{
		QStandardItemModel *newTabsModel = new QStandardItemModel (this);
		QStandardItem *defaultItem = new QStandardItem (tr ("Context-dependent"));
		defaultItem->setData ("contextdependent", Qt::UserRole);
		newTabsModel->appendRow (defaultItem);

		QObjectList multitabs = Core::Instance ()
				.GetPluginManager ()->GetAllCastableRoots<IHaveTabs*> ();
		Q_FOREACH (QObject *object, multitabs)
		{
			IInfo *ii = qobject_cast<IInfo*> (object);
			IHaveTabs *iht = qobject_cast<IHaveTabs*> (object);
			Q_FOREACH (const TabClassInfo& info, iht->GetTabClasses ())
			{
				QStandardItem *item =
						new QStandardItem (ii->GetName () + ": " + info.VisibleName_);
				item->setToolTip (info.Description_);
				item->setIcon (info.Icon_);
				item->setData (ii->GetUniqueID () + '|' + info.TabClass_, Qt::UserRole);
				newTabsModel->appendRow (item);
			}
		}
	void SeparateTabWidget::handleAddDefaultTab ()
	{
		const auto& combined = XmlSettingsManager::Instance ()->
				property ("DefaultNewTab").toString ().toLatin1 ();
		if (combined != "contextdependent")
		{
			const auto& parts = combined.split ('|');
			if (parts.size () != 2)
				qWarning () << Q_FUNC_INFO
						<< "incorrect split"
						<< parts
						<< combined;
			else
			{
				const QByteArray& newTabId = parts.at (0);
				const QByteArray& tabClass = parts.at (1);
				QObject *plugin = Core::Instance ()
						.GetPluginManager ()->GetPluginByID (newTabId);
				IHaveTabs *iht = qobject_cast<IHaveTabs*> (plugin);
				if (!iht)
					qWarning () << Q_FUNC_INFO
							<< "plugin with id"
							<< newTabId
							<< "is not a IMultiTabs";
				else
				{
					iht->TabOpenRequested (tabClass);
					return;
				}
			}
		}

		IHaveTabs *highestIHT = 0;
		QByteArray highestTabClass;
		int highestPriority = 0;
		for (auto iht : Core::Instance ().GetPluginManager ()->GetAllCastableTo<IHaveTabs*> ())
			for (const auto& info : iht->GetTabClasses ())
			{
				if (!(info.Features_ & TFOpenableByRequest))
					continue;

				if (info.Priority_ <= highestPriority)
					continue;

				highestIHT = iht;
				highestTabClass = info.TabClass_;
				highestPriority = info.Priority_;
			}

		const auto imtw = qobject_cast<ITabWidget*> (CurrentWidget ());
		const int delta = 15;
		if (imtw && imtw->GetTabClassInfo ().Priority_ + delta > highestPriority)
		{
			highestIHT = qobject_cast<IHaveTabs*> (imtw->ParentMultiTabs ());
			highestTabClass = imtw->GetTabClassInfo ().TabClass_;
		}

		if (!highestIHT)
		{
			qWarning () << Q_FUNC_INFO
					<< "no IHT detected";
			return;
		}

		highestIHT->TabOpenRequested (highestTabClass);
	}