Beispiel #1
0
void MusicScanner::scanFolder(MusicLibraryItemRoot *library, const QString &topLevel, const QString &f,
                              QSet<FileOnlySong> &existing, int level)
{
    if (stopRequested) {
        return;
    }
    if (level<4) {
        QDir d(f);
        QFileInfoList entries=d.entryInfoList(QDir::Files|QDir::NoSymLinks|QDir::Dirs|QDir::NoDotAndDotDot);
        MusicLibraryItemArtist *artistItem = 0;
        MusicLibraryItemAlbum *albumItem = 0;
        foreach (const QFileInfo &info, entries) {
            if (stopRequested) {
                return;
            }
            if (info.isDir()) {
                scanFolder(library, topLevel, info.absoluteFilePath(), existing, level+1);
            } else if(info.isReadable()) {
                Song song;
                QString fname=info.absoluteFilePath().mid(topLevel.length());

                if (fname.endsWith(".jpg", Qt::CaseInsensitive) || fname.endsWith(".png", Qt::CaseInsensitive) ||
                    fname.endsWith(".lyrics", Qt::CaseInsensitive) || fname.endsWith(".pamp", Qt::CaseInsensitive)) {
                    continue;
                }
                song.file=fname;
                QSet<FileOnlySong>::iterator it=existing.find(song);
                if (existing.end()==it) {
                    song=Tags::read(info.absoluteFilePath());
                    song.file=fname;
                } else {
                    song=*it;
                    existing.erase(it);
                }
                if (song.isEmpty()) {
                    continue;
                }
                count++;
                int t=time(NULL);
                if ((t-lastUpdate)>=2 || 0==(count%5)) {
                    lastUpdate=t;
                    emit songCount(count);
                }

                song.fillEmptyFields();
                song.size=info.size();
                if (!artistItem || song.artistOrComposer()!=artistItem->data()) {
                    artistItem = library->artist(song);
                }
                if (!albumItem || albumItem->parentItem()!=artistItem || song.albumName()!=albumItem->data()) {
                    albumItem = artistItem->album(song);
                }
                MusicLibraryItemSong *songItem = new MusicLibraryItemSong(song, albumItem);
                albumItem->append(songItem);
                albumItem->addGenre(song.genre);
                artistItem->addGenre(song.genre);
                library->addGenre(song.genre);
            }
        }
    }
void    TvmBarDataProxy::generate(const QSet<qint64>& rowKeys, int rowCount, int tvmRowIndex)
{
    qDebug() << "qps::TvmBarDataProxy::generate(): tvm=" << _tvm.data();
    if ( !getTvm() ) {
        resetArray(nullptr);
        return;
    }
    if ( tvmRowIndex >= rowCount ) {
        qWarning() << "qps::TvmBarDataProxy::generate(): Warning: row >= rowCount.";
        return;
    }

    // Generate empty rows for all tvms (ie for rowCount)
    QBarDataArray* barDataArray = new QBarDataArray{};
    barDataArray->reserve(rowCount);
    for ( int r = 0; r < rowCount; r++ )
        barDataArray->append(new QBarDataRow{});

    // Generate a row with rowKeys.size() columns for the TVM
    QBarDataRow* tvmBarDataRow = new QBarDataRow(rowKeys.size());
    auto i = _tvm->getMap().constBegin();
    while ( i != _tvm->getMap().constEnd() ) {
        QSet<qint64>::const_iterator rowIndexIter = rowKeys.find(i.key());
        if ( rowIndexIter != rowKeys.constEnd()) {
            int rowIndex = std::distance(rowKeys.cbegin(), rowIndexIter);
            if ( rowIndex >= 0 &&
                 rowIndex < tvmBarDataRow->size() )
                (*tvmBarDataRow)[rowIndex].setValue( static_cast<float>(i.value()));
        }
        ++i;
    }
    barDataArray->replace(tvmRowIndex, tvmBarDataRow);   // Finnaly replace empty tvm row with the tvm data row
    resetArray(barDataArray);
}
void Manager::gotoLocations(const QList<QVariant> &list)
{
    QSet<SymbolLocation> locations = Utils::roleToLocations(list);
    if (locations.size() == 0)
        return;

    // Default to first known location
    SymbolLocation loc = *locations.constBegin();

    if (locations.size() > 1) {
        // The symbol has multiple locations. Check if we are already at one location,
        // and if so, cycle to the "next" one
        auto textEditor = qobject_cast<TextEditor::BaseTextEditor *>(EditorManager::currentEditor());
        if (textEditor) {
            // check if current cursor position is a known location of the symbol
            const QString fileName = textEditor->document()->filePath().toString();
            int line;
            int column;
            textEditor->convertPosition(textEditor->position(), &line, &column);
            SymbolLocation current(fileName, line, column);
            QSet<SymbolLocation>::const_iterator it = locations.find(current);
            QSet<SymbolLocation>::const_iterator end = locations.constEnd();
            if (it != end) {
                // we already are at the symbol, cycle to next location
                ++it;
                if (it == end)
                    it = locations.begin();
                loc = *it;
            }
        }
    }
    gotoLocation(loc.fileName(), loc.line(), loc.column());
}
toConnectionSub *toQPSqlConnectionImpl::createConnection(void)
{
    // TODO shouldn't be this method reenteant?
    static QAtomicInt ID_COUNTER(0);
    int ID = ID_COUNTER.fetchAndAddAcquire(1);

    QString dbName = QString::number(ID);
    QSqlDatabase db = QSqlDatabase::addDatabase(parentConnection().provider(), dbName);
    db.setDatabaseName(parentConnection().database());
    QString host = parentConnection().host();
    int pos = host.indexOf(QString(":"));
    if (pos < 0)
        db.setHostName(host);
    else
    {
        db.setHostName(host.mid(0, pos));
        db.setPort(host.mid(pos + 1).toInt());
    }

    QString opt;

    QSet<QString> options = parentConnection().options();
    if (options.find("Compress") != options.end())
        opt += ";CLIENT_COMPRESS";
    if (options.find("Ignore Space") != options.end())
        opt += ";CLIENT_IGNORE_SPACE";
    if (options.find("No Schema") != options.end())
        opt += ";CLIENT_NO_SCHEMA";
    if (options.find("SSL") != options.end())
        opt += ";CLIENT_SSL";

    if (!opt.isEmpty())
        db.setConnectOptions(opt.mid(1)); // Strip first ; character

    db.open(parentConnection().user(), parentConnection().password());
    if (!db.isOpen())
    {
        QString t = toQPSqlConnectionSub::ErrorString(db.lastError());
        QSqlDatabase::removeDatabase(dbName);
        throw t;
    }

    toQPSqlConnectionSub *ret = new toQPSqlConnectionSub(parentConnection(), db, dbName);
    return ret;
}
void ClassSpaceChecker::onPackageReportItemSelectionChanged()
{
	QList<QTableWidgetItem *> items = ui.tableWidgetPackageReport->selectedItems();
	if(items.size() <= 0)
	{
		ui.lineEdit_Result->setText(prevTotalResultStr_);
		return;
	}

	QSet<int> set;
	int classCount = 0;
	int uniqueClassCount = 0;
	int diffClassCount = 0;
	int totalSize = 0;
	for(int i = 0; i < items.size(); i++) 
	{
		QTableWidgetItem *item = items.at(i);
		int row = item->row();
		if(set.find(row) != set.end())
			continue;

		QTableWidgetItem *itemClassCount = ui.tableWidgetPackageReport->item(item->row(), 1);
		if(itemClassCount == NULL)
			continue;
		classCount += itemClassCount->data(Qt::DisplayRole).toInt();

		QTableWidgetItem *itemUniqueClassCount = ui.tableWidgetPackageReport->item(item->row(), 2);
		if(itemUniqueClassCount == NULL)
			continue;
		uniqueClassCount += itemUniqueClassCount->data(Qt::DisplayRole).toInt();

		QTableWidgetItem *itemDiffClassCount = ui.tableWidgetPackageReport->item(item->row(), 3);
		if(itemDiffClassCount == NULL)
			continue;
		diffClassCount += itemDiffClassCount->data(Qt::DisplayRole).toInt();

		QTableWidgetItem *itemFileSize = ui.tableWidgetPackageReport->item(item->row(), 5);
		if(itemFileSize == NULL)
			continue;
		totalSize += itemFileSize->data(Qt::DisplayRole).toInt();
		set.insert(row);
	}


	QString resultStr;
	resultStr += "All Class Count : ";
	resultStr += QString::number(classCount);
	resultStr += ", Unique Class Count : ";
	resultStr += QString::number(uniqueClassCount);
	resultStr += ", Diff Class Count : ";
	resultStr += QString::number(diffClassCount);
	resultStr += ", File Size : ";
	resultStr += numberDot(QString::number(totalSize));
	resultStr += " bytes";

	ui.lineEdit_Result->setText(resultStr);
}
Beispiel #6
0
static QSet<QByteArray> activeConditions()
{
    QSet<QByteArray> result = keywords();

    QByteArray distributionName = QSysInfo::productType().toLower().toUtf8();
    QByteArray distributionRelease = QSysInfo::productVersion().toLower().toUtf8();
    if (!distributionName.isEmpty()) {
        if (result.find(distributionName) == result.end())
            result.insert(distributionName);
        if (!distributionRelease.isEmpty()) {
            QByteArray versioned = distributionName + "-" + distributionRelease;
            if (result.find(versioned) == result.end())
                result.insert(versioned);
        }
    }

    return result;
}
Beispiel #7
0
///Return the list of contact from history (in order, most recently used first)
CALLMODEL_TEMPLATE QHash<Contact*, QDateTime> SORTABLE_T::getContactListByTime(/*ContactList list*/)
{
   const CallMap& history= CallModel<CallWidget,Index>::getHistory();
   QHash<Contact*, QDateTime> toReturn;
   QSet<QString> alreadyUsed;
   QMapIterator<QString, Call*> i(history);
   i.toBack();
   while (i.hasPrevious()) { //Iterate from the end up
      i.previous();
      (alreadyUsed.find(i.value()->getPeerPhoneNumber()) == alreadyUsed.constEnd()); //Don't ask, leave it there Elv13(2012)
      if (alreadyUsed.find(i.value()->getPeerPhoneNumber()) == alreadyUsed.constEnd()) {
         Contact* contact = AkonadiBackend::getInstance()->getContactByPhone(i.value()->getPeerPhoneNumber(),true);
         if (contact && toReturn.find(contact) == toReturn.end()) {
            toReturn[contact] = QDateTime::fromTime_t(i.value()->getStartTimeStamp().toUInt());
         }
         alreadyUsed << i.value()->getPeerPhoneNumber();
      }
   }
   return toReturn;
}
void Manager::gotoLocations(const QList<QVariant> &list)
{
    QSet<SymbolLocation> locations = Utils::roleToLocations(list);

    if (locations.count() == 0)
        return;

    QString fileName;
    int line = 0;
    int column = 0;
    bool currentPositionAvailable = false;

    // what is open now?
    Core::IEditor *editor = Core::EditorManager::instance()->currentEditor();
    if (editor) {
        // get current file name
        Core::IDocument *document = editor->document();
        if (document)
            fileName = document->fileName();

        // if text file - what is current position?
        TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor *>(editor);
        if (textEditor) {
            // there is open currently text editor
            int position = textEditor->position();
            textEditor->convertPosition(position, &line, &column);
            currentPositionAvailable = true;
        }
    }

    // if there is something open - try to check, is it currently activated symbol?
    if (currentPositionAvailable) {
        SymbolLocation current(fileName, line, column);
        QSet<SymbolLocation>::const_iterator it = locations.find(current);
        QSet<SymbolLocation>::const_iterator end = locations.constEnd();
        // is it known location?
        if (it != end) {
            // found - do one additional step
            ++it;
            if (it == end)
                it = locations.begin();
            const SymbolLocation &found = *it;
            gotoLocation(found.fileName(), found.line(), found.column());
            return;
        }
    }

    // no success - open first item in the list
    const SymbolLocation loc = *locations.constBegin();

    gotoLocation(loc.fileName(), loc.line(), loc.column());
}
Beispiel #9
0
void Session::processProjects(const QList<ProjectInfo> &projects)
{
	QSet<QString> projectsSet = QSet<QString>::fromList(m_projects.keys());
	QList<QString> added;
	QList<QString> changed;

	// Zistenie zmien v projektoch a ich aktualizácia
	foreach(const ProjectInfo &project, projects) {
		const QString masterURL = project.primaryKey();

		QSet<QString>::iterator projectIterator = projectsSet.find(project.primaryKey());

		// Projekt ešte nie je v zozname projektov
		if (projectIterator == projectsSet.end()) {
			m_projects.insert(masterURL, project);
			createProjectData(masterURL);
			added.append(masterURL);
		}
		else {
			if (project != this->project(masterURL)) {
				m_projects.insert(masterURL, project);
				changed.append(masterURL);
			}
			projectsSet.erase(projectIterator);
		}
	}

	if (!added.isEmpty()) {
		emit projectsAdded(added, m_id);
	}
	if (!projectsSet.isEmpty()) {
		emit projectsRemoved(projectsSet.toList(), m_id);
	}
	if (!changed.isEmpty()) {
		emit projectsChanged(changed, m_id);
	}

	foreach(const QString &masterURL, projectsSet) {
		m_projects.remove(masterURL);
		removeProjectData(masterURL);
	}
void ClassSpaceChecker::onResultItemSelectionChanged()
{
	QList<QTableWidgetItem *> items = ui.tableWidgetResult->selectedItems();
	if(items.size() <= 0)
	{
		ui.lineEdit_Result->setText(prevTotalResultStr_);
		return;
	}

	QSet<int> set;
	int classCount = 0;
	int methodCount = 0;
	int totalSize = 0;
	for(int i = 0; i < items.size(); i++) 
	{
		QTableWidgetItem *item = items.at(i);
		int row = item->row();
		if(set.find(row) != set.end())
			continue;

		totalSize += getIntFromTableItem(ui.tableWidgetResult, item->row(), 1);
		methodCount += getIntFromTableItem(ui.tableWidgetResult, item->row(), 3);

		classCount++;

		set.insert(row);
	}


	QString resultStr;
	resultStr += "Selected Count : ";
	resultStr += QString::number(classCount);
	resultStr += ", FileSize : ";
	resultStr += numberDot(QString::number(totalSize));
	resultStr += " bytes";
	resultStr += ", Method : ";
	resultStr += QString::number(methodCount);

	ui.lineEdit_Result->setText(resultStr);
}
void UBFeaturesComputingThread::scanFS(const QUrl & currentPath, const QString & currVirtualPath, const QSet<QUrl> &pFavoriteSet)
{
//    Q_ASSERT(QFileInfo(currentPath.toLocalFile()).exists());
//    if(QFileInfo(currentPath.toLocalFile()).exists())
//        return;

    QFileInfoList fileInfoList = UBFileSystemUtils::allElementsInDirectory(currentPath.toLocalFile());

    QFileInfoList::iterator fileInfo;
    for ( fileInfo = fileInfoList.begin(); fileInfo != fileInfoList.end(); fileInfo +=  1) {
        if (abort) {
            return;
        }

        QString fullFileName = fileInfo->absoluteFilePath();
        UBFeatureElementType featureType = UBFeaturesController::fileTypeFromUrl(fullFileName);
        QString fileName = fileInfo->fileName();

        QImage icon = UBFeaturesController::getIcon(fullFileName, featureType);

        if ( fullFileName.contains(".thumbnail."))
            continue;

        UBFeature testFeature(currVirtualPath + "/" + fileName, icon, fileName, QUrl::fromLocalFile(fullFileName), featureType);

        emit sendFeature(testFeature);
        emit featureSent();
        emit scanPath(fullFileName);

        if ( pFavoriteSet.find(QUrl::fromLocalFile(fullFileName)) != pFavoriteSet.end()) {
            //TODO send favoritePath from the controller or make favoritePath public and static
            emit sendFeature(UBFeature( UBFeaturesController::favoritePath + "/" + fileName, icon, fileName, QUrl::fromLocalFile(fullFileName), featureType));
        }

        if (featureType == FEATURE_FOLDER) {
            scanFS(QUrl::fromLocalFile(fullFileName), currVirtualPath + "/" + fileName, pFavoriteSet);
        }
    }
}
void CFontFileList::fileDuplicates(const QString &folder, const QSet<TFile> &files)
{
    QDir dir(folder);

    dir.setFilter(QDir::Files|QDir::Hidden);

    QFileInfoList list(dir.entryInfoList());

    for (int i = 0; i < list.size() && !itsTerminated; ++i)
    {
        QFileInfo fileInfo(list.at(i));

        // Check if this file is already know about - this will do a case-sensitive comparison
        if(!files.contains(TFile(fileInfo.fileName())))
        {
            // OK, not found - this means it is a duplicate, but different case. So, find the
            // FontMap iterator, and update its list of files.
            QSet<TFile>::ConstIterator entry=files.find(TFile(fileInfo.fileName(), true));

            if(entry!=files.end())
                (*((*entry).it)).insert(fileInfo.absoluteFilePath());
        }
    }
}
toConnectionSub* toOracleConnectionImpl::createConnection(void)
{
    ::trotl::OciConnection *conn = NULL;
    ::trotl::OciLogin *login = NULL;
    QString oldSid;

    QSet<QString> options = parentConnection().options();

    bool sqlNet = (options.find("SQL*Net") != options.end());
    if (!sqlNet)
    {
        oldSid = qgetenv("ORACLE_SID");
        qputenv("ORACLE_SID", parentConnection().database().toLatin1());
    }
    try
    {
        int session_mode = OCI_DEFAULT;
        if (options.find("SYS_OPER") != options.end())
            session_mode = OCI_SYSOPER;
        else if (options.find("SYS_DBA") != options.end())
            session_mode = OCI_SYSDBA;
#ifdef OCI_SYSASM
        else if (options.find("SYS_ASM") != options.end())
            session_mode = OCI_SYSASM;
#endif

        do
        {
            /* TODO
               if (!sqlNet)
               conn->server_attach();
               else
            */
            QString user = parentConnection().user();
            QString pass = parentConnection().password();

            try
            {
                // TODO what does _login destructor? and where is it?
                /*::trotl::OciLogin */ login = new ::trotl::OciLogin(_env,
                        ::trotl::LoginPara(
                            user.isEmpty() ? "" : user.toUtf8().constData(),
                            pass.isEmpty() ? "" : pass.toUtf8().constData(),
                            parentConnection().database().toUtf8().constData()
                        ),
                        (ub4) session_mode);
                conn = new ::trotl::OciConnection(_env, *login);

                TLOG(5, toDecorator, __HERE__) << "Oracle database version: "
                                               << ::std::hex << ::std::showbase << ::std::setw(10)
                                               << ::std::setfill('0') << ::std::internal
                                               << login->_server._version << ::std::endl
                                               << login->_server._version_string << ::std::endl
                                               << login->_server.versionNumber() << "."
                                               << login->_server.releaseNumber() << "."
                                               << login->_server.updateNumber() << "."
                                               << login->_server.portReleaseNumber() << "."
                                               << login->_server.portUpdateNumber()
                                               << ::std::dec << ::std::endl;
            }
            catch (const ::trotl::OciException &exc)
            {
                TLOG(5, toDecorator, __HERE__) << "TODO: catch" << std::endl << __HERE__ << std::endl;

                if (/*toThread::mainThread() &&*/ exc.get_code() == 28001)
                {
                    bool ok = false;
                    QString newpass = QInputDialog::getText(
                                          Utils::toQMainWindow(),
                                          qApp->translate("toOracleConnection", "Password expired"),
                                          qApp->translate("toOracleConnection", "Enter new password"),
                                          QLineEdit::Password,
                                          QString::null,
                                          &ok);
                    if (!ok)
                        throw exc;

                    QString newpass2 = QInputDialog::getText(
                                           Utils::toQMainWindow(),
                                           qApp->translate("toOracleConnection", "Password expired"),
                                           qApp->translate("toOracleConnection", "Enter password again for confirmation"),
                                           QLineEdit::Password,
                                           QString::null,
                                           &ok);

                    if (!ok)
                        throw exc;

                    if (newpass2 != newpass)
                        throw qApp->translate("toOracleConnection", "The two passwords doesn't match");
                    QString nputf = newpass;
                    if ( login ) delete login;
                    login = new ::trotl::OciLogin(_env,
                                                  ::trotl::LoginAndPChangePara(
                                                      user.isEmpty() ? "" : user.toUtf8().constData(),
                                                      pass.isEmpty() ? "" : pass.toUtf8().constData(),
                                                      newpass.isEmpty() ? "" : newpass.toUtf8().constData(),
                                                      parentConnection().database().toUtf8().constData()
                                                  ),
                                                  (ub4) session_mode);
                    conn = new ::trotl::OciConnection(_env, *login);

                    parentConnection().setPassword(newpass);
                }
                else
                {
                    throw exc;
                } //  (toThread::mainThread() && exc.get_code() == 28001)
            } // catch (const ::trotl::OciException &exc)
        }
        while (!conn);
    }
    catch (const ::trotl::OciException &exc)
    {
        if (!sqlNet)
        {
            if (oldSid.isNull())
                qputenv("ORACLE_SID", "");
            else
                qputenv("ORACLE_SID", oldSid.toLatin1());
        }
        delete conn;
        ReThrowException(exc);
    }
    if (!sqlNet)
    {
        if (oldSid.isNull())
            qputenv("ORACLE_SID", "");
        else
        {
            qputenv("ORACLE_SID", oldSid.toLatin1());
        }
    }

    try
    {
        QString alterSessionSQL = QString::fromLatin1("ALTER SESSION SET NLS_DATE_FORMAT = '");
        alterSessionSQL += toConfigurationNewSingle::Instance().option(ToConfiguration::Oracle::ConfDateFormat).toString();
        alterSessionSQL += QString::fromLatin1("'");
        oracleQuery::trotlQuery date(*conn, qPrintable(alterSessionSQL));
    }
    catch (...)
    {
        TLOG(5, toDecorator, __HERE__)
                << "Failed to set new default date format for session: "
                << toConfigurationNewSingle::Instance().option(ToConfiguration::Oracle::ConfDateFormat).toString()
                << std::endl;
        Utils::toStatusMessage(QObject::tr("Failed to set new default date format for session: %1")
                               .arg(toConfigurationNewSingle::Instance().option(ToConfiguration::Oracle::ConfDateFormat).toString()));
    }

    try
    {
        QString alterSessionSQL = QString::fromLatin1("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = '");
        alterSessionSQL += toConfigurationNewSingle::Instance().option(ToConfiguration::Oracle::ConfTimestampFormat).toString();
        alterSessionSQL += QString::fromLatin1("'");
        oracleQuery::trotlQuery timestmp(*conn, qPrintable(alterSessionSQL));
    }
    catch (::trotl::OciException const& e)
    {
        TLOG(5, toDecorator, __HERE__)
                << "Failed to set new default timestmp format for session: "
                << toConfigurationNewSingle::Instance().option(ToConfiguration::Oracle::ConfTimestampFormat).toString()
                << std::endl
                << e.what();
        Utils::toStatusMessage(QObject::tr("Failed to set new default timestamp format for session: %1")
                               .arg(toConfigurationNewSingle::Instance().option(ToConfiguration::Oracle::ConfTimestampFormat).toString()));
    }
    catch (...)
    {
        TLOG(5, toDecorator, __HERE__)
                << "Failed to set new default timestmp format for session: "
                << toConfigurationNewSingle::Instance().option(ToConfiguration::Oracle::ConfTimestampFormat).toString()
                << std::endl;
        Utils::toStatusMessage(QObject::tr("Failed to set new default timestamp format for session: %1")
                               .arg(toConfigurationNewSingle::Instance().option(ToConfiguration::Oracle::ConfTimestampFormat).toString()));
    }

    try
    {
        oracleQuery::trotlQuery info(*conn,
                                     "BEGIN\n"
                                     "  SYS.DBMS_APPLICATION_INFO.SET_CLIENT_INFO('" TOAPPNAME " " TORAVERSION
                                     " (http://tora.sf.net)"
                                     "');\n"
                                     "  SYS.DBMS_APPLICATION_INFO.SET_MODULE('" TOAPPNAME "','Access Database');\n"
                                     "END;");
    }
    catch (::trotl::OciException const& e)
    {
        TLOG(5, toDecorator, __HERE__) << "Failed to set client info for session:\n" << e.what();
    }
    catch (...)
    {
        TLOG(5, toDecorator, __HERE__) << "Failed to set client info for session\n";
    }

    return new toOracleConnectionSub(conn, login);
}
Beispiel #14
0
bool ChessModel::isMovable(char player, QPair<int, int> st, QPair<int, int> ed) const
{
    if (player == 'A') {
        st.first = 14 - st.first;
        st.second = 6 - st.second;
        ed.first = 14 - ed.first;
        ed.second = 6 - ed.second;
    }
    if (st.first < 1 || st.first > 13 || st.second < 1 || st.second > 5 ||
            ed.first < 1 || ed.first > 13 || ed.second < 1 || ed.second > 5) return 0;
    if (getChessId(player, ed) != -1) return 0;
    if (getChessId(player, st) == -1) return 0;
    if (isHouse(ed) && (getChessId('A' + 'B' - player, ed) != -1)) return 0;

    int pt = pieceType[getChessId(player, st)];
    if (pt == 10 || pt == 12) return 0;

    if (ed.first == 7  && (ed.second == 2 || ed.second == 4)) return 0;
    if ((st.first == 1 || st.first == 13) && (st.second == 2 || st.second == 4)) return 0;
    int dis = abs(st.first - ed.first) + abs(st.second - ed.second);

    if (dis == 1) return 1;
    if (dis == 2 && (isHouse(st) || isHouse(ed))) return 1;

    if (isRail(st) && isRail(ed)) {
        if (st.first == ed.first) {
            bool flag = 1;
            for (int i = qMin(st.second, ed.second) + 1; i <= qMax(st.second, ed.second) - 1; i++)
                if (getChessId('A', qMakePair(st.first, i)) != -1 || getChessId('B', qMakePair(st.first, i)) != -1)
                    flag = 0;
            if (flag) return 1;
        }
        if (st.second == ed.second) {
            bool flag = 1;
            for (int i = qMin(st.first, ed.first) + 1; i <= qMax(st.first, ed.first) - 1; i++)
                if (getChessId('A', qMakePair(i, st.second)) != -1 || getChessId('B', qMakePair(i, st.second)) != -1)
                    flag = 0;
            if (flag) return 1;
        }
        if (pt != 9) return 0;
        QQueue< QPair<int, int> > queue;
        QSet< QPair<int, int> > set;
        queue.push_back(st);
        while (!queue.empty()) {
            QPair<int, int> now = queue.front();
            queue.pop_front();
            for (int i = 0; i < 4; i++) {
                QPair<int, int> tmp = now;
                tmp.first += dx[i];
                tmp.second += dy[i];
                if (isRail(tmp) && getChessId('A', tmp) == -1 && getChessId('B', tmp) == -1 && set.find(tmp) == set.end()) {
                    queue.push_back(tmp);
                    set.insert(tmp);
                }
            }
        }
        for (auto itm : set) {
            if (qAbs(itm.first - ed.first) + qAbs(itm.second - ed.second) <= 1)
                return 1;
        }
    }
    return 0;
}