void ShiftMachine::setup(LayoutUpdater *updater) { if (not updater) { qCritical() << __PRETTY_FUNCTION__ << "No updater specified. Aborting setup."; return; } setChildMode(QState::ExclusiveStates); QState *no_shift = 0; QState *latched_shift = 0; QState *caps_lock = 0; // addState makes state machine to be a parent of passed state, // so we don't have to care about deleting states explicitly. addState(no_shift = new QState); addState(latched_shift = new QState); addState(caps_lock = new QState); setInitialState(no_shift); no_shift->setObjectName(no_shift_state); latched_shift->setObjectName(latched_shift_state); caps_lock->setObjectName(caps_lock_state); connect(no_shift, SIGNAL(entered()), updater, SLOT(syncLayoutToView())); connect(latched_shift, SIGNAL(entered()), updater, SLOT(syncLayoutToView())); connect(caps_lock, SIGNAL(entered()), updater, SLOT(syncLayoutToView())); no_shift->addTransition(updater, SIGNAL(shiftPressed()), latched_shift); no_shift->addTransition(updater, SIGNAL(autoCapsActivated()), latched_shift); latched_shift->addTransition(updater, SIGNAL(shiftCancelled()), no_shift); latched_shift->addTransition(updater, SIGNAL(shiftReleased()), caps_lock); caps_lock->addTransition(updater, SIGNAL(shiftReleased()), no_shift); // Defer to first main loop iteration: QTimer::singleShot(0, this, SLOT(start())); }
void TscoreMeasure::prependNotes(QList<TscoreNote*>& nl) { QList<TscoreNote*> notesToOut; Tnote newNote; // new note that has to be created when rhythm duration is split int notesDur = groupDuration(nl); if (nl.first()->note()->rhythm() != Trhythm::e_none && m_free - notesDur < 0) // move notes to the next measure if not enough space releaseAtEnd(notesDur, notesToOut, newNote); for (int i = 0; i < nl.size(); ++i) { m_notes.insert(i, nl[i]); connect(nl[i], &TscoreNote::noteGoingToChange, this, &TscoreMeasure::noteChangedSlot); } updateRhythmicGroups(); resolveBeaming(m_notes.first()->rhythmGroup()); checkBarLine(); for (TscoreBeam* b : m_beams) b->performBeaming(); shiftReleased(notesToOut, newNote); content(this); }
void AppWindow::keyReleaseEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Shift) { shiftReleased(); } }
//################################################################################################# //################### PROTECTED ############################################ //################################################################################################# void TscoreMeasure::noteChangedSlot(TscoreNote* sn) { Tnote newNote; // new note that has to be created when rhythm duration is split QList<TscoreNote*> notesToOut; if (sn->rhythmChanged()) { // TODO: if new duration of changed note is longer than whole measure duration - split it here and create new measure with single note // - still we don't know new pitch int prevDur = sn->rhythm()->duration(); int newDur = sn->note()->duration(); int nextMeasDur = 0; qDebug() << debug() << "rhythm changed from" << sn->rhythm()->string() << "to" << sn->note()->rtm.string() << "free" << m_free; if (m_free - (newDur - prevDur) < 0) { // There is not enough space for this note with longer duration /** 1. Try to release measure (move notes after this @p sn one to the next measure) */ int leftDur = releaseAtEnd(newDur - prevDur - m_free, notesToOut, newNote, sn->index() - firstNoteId() + 1); if (leftDur) { sn->moveNote(sn->note()->isRest() ? 0 : sn->newNotePos()); // update position of note head sn->staff()->updatePitch(sn->index()); // update Tnote according to new head position /** 2. There is still not enough space for new duration - splitting duration of this @p sn note to fill free space in this measure * and create part of that duration in the next one */ nextMeasDur = newDur - (m_free + prevDur); Trhythm oldRhythm(sn->note()->rtm); Trhythm newRtmOfChanged(m_free + prevDur); if (newRtmOfChanged.rhythm() == Trhythm::e_none) { /** 3. Unfortunately remained free space in the measure can't be filled with single rhythm value */ qDebug() << debug() << "To fill measure with remaining duration need to split note of" << m_free + prevDur; TrhythmList solvedList; Trhythm::resolve(m_free + prevDur, solvedList); if (solvedList.size() == 2) { solvedList.first().setRest(oldRhythm.isRest()); solvedList.last().setRest(oldRhythm.isRest()); sn->note()->rtm.setRhythm(solvedList.first().duration()); copyRhythmParams(sn, oldRhythm); Tnote n2(*sn->note(), solvedList.last()); // TODO: common code with @p split auto inserted = m_staff->insertNote(n2, sn->index() + 1, sn->isReadOnly()); fixStemDirection(inserted); m_notes.insert(inserted->index() - firstNoteId(), inserted); connect(inserted, &TscoreNote::noteGoingToChange, this, &TscoreMeasure::noteChangedSlot); // inserted->setGroup(sn->group()); m_staff->updateNotesPos(inserted->index()); if (!sn->note()->isRest()) restoreTie(oldRhythm.tie(), sn); } else qDebug() << debug() << "Can not resolve duration of" << m_free + prevDur; } else { sn->note()->rtm.setRhythm(newRtmOfChanged); copyRhythmParams(sn, oldRhythm); } } qDebug() << debug() << "RECALCULATED, remained" << nextMeasDur; updateRhythmicGroups(); resolveBeaming(sn->rhythmGroup()); checkBarLine(); if (nextMeasDur) { /** 4. At the beginning of the next staff, create new note of the same pitch with remaining duration. */ Trhythm nextMeasRtm(nextMeasDur); if (nextMeasRtm.rhythm() == Trhythm::e_none) { splitThenInsert(nextMeasDur, lastNoteId() + 1, *sn->note(), sn->isReadOnly()); } else { auto nextMeasNote = m_staff->insertNote(lastNoteId() + 1, Tnote(*sn->note(), nextMeasRtm), sn->isReadOnly()); fixStemDirection(nextMeasNote); } if (!sn->note()->isRest()) lastNote()->tieWithNext(); } } else if (newDur == prevDur) { if (sn->note()->isRest() != sn->rhythm()->isRest()) qDebug() << debug() << "note" << sn->index() << "changed to/from rest"; resolveBeaming(sn->rhythmGroup(), sn->rhythmGroup()); checkBarLine(); } else { // measure duration is less than meter - take notes from the next measure m_free += prevDur - newDur; qDebug() << debug() << "needs duration" << m_free; fill(); } } shiftReleased(notesToOut, newNote); }
void TscoreMeasure::insertNote(int id, TscoreNote* sn) { // qDebug() << debug() << sn->note()->rtm.xmlType() << "inserting id" << id << "count" << m_notes.count() << "free" << m_free; int noteDur = sn->note()->duration(); int resolveAfter = 0; // un-resolvable duration of new note QList<TscoreNote*> notesToOut; Tnote newNote; // new note that has to be created when rhythm duration is split if (sn->note()->rhythm() != Trhythm::e_none && m_free - noteDur < 0) { // move notes to the next measure if not enough space int toRelease = releaseAtEnd(noteDur - m_free, notesToOut, newNote, id); if (toRelease > 0) { // There is still not enough space if (m_free > 0) { // measure has some free space for the new note but not for entire if (Trhythm(m_free).rhythm() == Trhythm::e_none) { Trhythm subRhythm(noteDur - m_free, sn->note()->isRest()); subRhythm.setTie(sn->note()->rtm.tie()); subRhythm.setStemDown(sn->note()->rtm.stemDown()); if (subRhythm.rhythm() == Trhythm::e_none) qDebug() << debug() << "can not shrink note to duration" << noteDur - m_free; sn->setRhythm(subRhythm); splitThenInsert(m_free, id, *sn->note(), sn->isReadOnly()); insertNote(lastNoteId() + 1, sn); if (!sn->note()->isRest()) lastNote()->tieWithNext(); return; } Trhythm oldRhythm(sn->note()->rtm); sn->setRhythm(Trhythm(m_free, sn->note()->isRest())); copyRhythmParams(sn, oldRhythm); // sn->note()->rtm.setTie(oldRhythm.tie()); // sn->note()->rtm.setStemDown(oldRhythm.stemDown()); if (newNote.rhythm() != Trhythm::e_none) // TODO: remove when tested qDebug() << "NEW NOTE is already created!!!"; Trhythm newRtm(noteDur - m_free, sn->note()->isRest()); if (newRtm.rhythm() == Trhythm::e_none) // two notes have to be added resolveAfter = noteDur - m_free; // do it after else newNote = Tnote(*sn->note(), newRtm); noteDur = m_free; } else { // measure has not at all space qDebug() << debug() << "move entire note" << sn->note()->toText(); notesToOut << sn; m_staff->shiftToMeasure(m_staff->measures().indexOf(this) + 1, notesToOut); return; } } } m_free -= noteDur; m_notes.insert(id, sn); qDebug() << debug() << "measure got a note" << sn->note()->rtm.xmlType() << "FREE" << m_free << "out" << notesToOut.count(); connect(sn, &TscoreNote::noteGoingToChange, this, &TscoreMeasure::noteChangedSlot); updateRhythmicGroups(); resolveBeaming(sn->rhythmGroup()); checkBarLine(); shiftReleased(notesToOut, newNote); if (resolveAfter) { auto lastN = lastNote(); splitThenInsert(resolveAfter, lastN->index() + 1, *lastN->note(), lastN->isReadOnly()); } content(this); }
bool CmdPromptInput::eventFilter(QObject* obj, QEvent* event) { if(event->type() == QEvent::KeyPress) { if(isBlinking) emit stopBlinking(); QKeyEvent* pressedKey = (QKeyEvent*)event; //NOTE: These shortcuts need to be caught since QLineEdit uses them if(pressedKey->matches(QKeySequence::Cut)) { pressedKey->accept(); emit cutPressed(); return true; } else if(pressedKey->matches(QKeySequence::Copy)) { pressedKey->accept(); emit copyPressed(); return true; } else if(pressedKey->matches(QKeySequence::Paste)) { pressedKey->accept(); emit pastePressed(); return true; } else if(pressedKey->matches(QKeySequence::SelectAll)) { pressedKey->accept(); emit selectAllPressed(); return true; } else if(pressedKey->matches(QKeySequence::Undo)) { pressedKey->accept(); emit undoPressed(); return true; } else if(pressedKey->matches(QKeySequence::Redo)) { pressedKey->accept(); emit redoPressed(); return true; } int key = pressedKey->key(); switch(key) { case Qt::Key_Enter: case Qt::Key_Return: case Qt::Key_Space: pressedKey->accept(); processInput(QChar(key)); return true; break; case Qt::Key_Delete: pressedKey->accept(); emit deletePressed(); return true; break; case Qt::Key_Tab: pressedKey->accept(); emit tabPressed(); return true; break; case Qt::Key_Escape: pressedKey->accept(); prefix = "Command: "; clear(); emit appendHistory(curText + tr("*Cancel*")); emit escapePressed(); return true; break; case Qt::Key_F1: pressedKey->accept(); emit F1Pressed(); return true; break; case Qt::Key_F2: pressedKey->accept(); emit F2Pressed(); return true; break; case Qt::Key_F3: pressedKey->accept(); emit F3Pressed(); return true; break; case Qt::Key_F4: pressedKey->accept(); emit F4Pressed(); return true; break; case Qt::Key_F5: emit F5Pressed(); pressedKey->accept(); return true; break; case Qt::Key_F6: pressedKey->accept(); emit F6Pressed(); return true; break; case Qt::Key_F7: pressedKey->accept(); emit F7Pressed(); return true; break; case Qt::Key_F8: pressedKey->accept(); emit F8Pressed(); return true; break; case Qt::Key_F9: pressedKey->accept(); emit F9Pressed(); return true; break; case Qt::Key_F10: pressedKey->accept(); emit F10Pressed(); return true; break; case Qt::Key_F11: pressedKey->accept(); emit F11Pressed(); return true; break; case Qt::Key_F12: pressedKey->accept(); emit F12Pressed(); return true; break; case Qt::Key_Shift: pressedKey->ignore(); //we don't want to eat it, we just want to keep track of it emit shiftPressed(); break; default: pressedKey->ignore(); } } if(event->type() == QEvent::KeyRelease) { QKeyEvent* releasedKey = (QKeyEvent*)event; int key = releasedKey->key(); switch(key) { case Qt::Key_Shift: releasedKey->ignore(); //we don't want to eat it, we just want to keep track of it emit shiftReleased(); break; default: releasedKey->ignore(); } } return QObject::eventFilter(obj, event); }
CmdPrompt::CmdPrompt(QWidget* parent) : QWidget(parent) { qDebug("CmdPrompt Constructor"); setObjectName("Command Prompt"); promptInput = new CmdPromptInput(this); promptHistory = new CmdPromptHistory(); promptDivider = new QFrame(this); promptVBoxLayout = new QVBoxLayout(this); promptSplitter = new CmdPromptSplitter(this); this->setFocusProxy(promptInput); promptHistory->setFocusProxy(promptInput); promptDivider->setLineWidth(1); promptDivider->setFrameStyle(QFrame::HLine); promptDivider->setMaximumSize(QWIDGETSIZE_MAX, 1); promptVBoxLayout->addWidget(promptSplitter); promptVBoxLayout->addWidget(promptHistory); promptVBoxLayout->addWidget(promptDivider); promptVBoxLayout->addWidget(promptInput); promptVBoxLayout->setSpacing(0); promptVBoxLayout->setContentsMargins(0,0,0,0); this->setLayout(promptVBoxLayout); styleHash = new QHash<QString, QString>(); styleHash->insert("color", "#000000"); // Match -------| styleHash->insert("background-color", "#FFFFFF"); // | styleHash->insert("selection-color", "#FFFFFF"); // | styleHash->insert("selection-background-color", "#000000"); // Match -------| styleHash->insert("font-family", "Monospace"); styleHash->insert("font-style", "normal"); styleHash->insert("font-size", "12px"); updateStyle(); blinkState = false; blinkTimer = new QTimer(this); connect(blinkTimer, SIGNAL(timeout()), this, SLOT(blink())); this->show(); connect(promptInput, SIGNAL(stopBlinking()), this, SLOT(stopBlinking())); connect(promptInput, SIGNAL(appendHistory(const QString&)), promptHistory, SLOT(appendHistory(const QString&))); connect(this, SIGNAL(appendTheHistory(const QString&)), promptHistory, SLOT(appendHistory(const QString&))); //For use outside of command prompt connect(promptInput, SIGNAL(startCommand(const QString&)), this, SIGNAL(startCommand(const QString&))); connect(promptInput, SIGNAL(runCommand(const QString&, const QString&)), this, SIGNAL(runCommand(const QString&, const QString&))); connect(promptInput, SIGNAL(deletePressed()), this, SIGNAL(deletePressed())); connect(promptInput, SIGNAL(tabPressed()), this, SIGNAL(tabPressed())); connect(promptInput, SIGNAL(escapePressed()), this, SIGNAL(escapePressed())); connect(promptInput, SIGNAL(F1Pressed()), this, SIGNAL(F1Pressed())); connect(promptInput, SIGNAL(F2Pressed()), this, SIGNAL(F2Pressed())); connect(promptInput, SIGNAL(F3Pressed()), this, SIGNAL(F3Pressed())); connect(promptInput, SIGNAL(F4Pressed()), this, SIGNAL(F4Pressed())); connect(promptInput, SIGNAL(F5Pressed()), this, SIGNAL(F5Pressed())); connect(promptInput, SIGNAL(F6Pressed()), this, SIGNAL(F6Pressed())); connect(promptInput, SIGNAL(F7Pressed()), this, SIGNAL(F7Pressed())); connect(promptInput, SIGNAL(F8Pressed()), this, SIGNAL(F8Pressed())); connect(promptInput, SIGNAL(F9Pressed()), this, SIGNAL(F9Pressed())); connect(promptInput, SIGNAL(F10Pressed()), this, SIGNAL(F10Pressed())); connect(promptInput, SIGNAL(F11Pressed()), this, SIGNAL(F11Pressed())); connect(promptInput, SIGNAL(F12Pressed()), this, SIGNAL(F12Pressed())); connect(promptInput, SIGNAL(cutPressed()), this, SIGNAL(cutPressed())); connect(promptInput, SIGNAL(copyPressed()), this, SIGNAL(copyPressed())); connect(promptInput, SIGNAL(pastePressed()), this, SIGNAL(pastePressed())); connect(promptInput, SIGNAL(selectAllPressed()), this, SIGNAL(selectAllPressed())); connect(promptInput, SIGNAL(undoPressed()), this, SIGNAL(undoPressed())); connect(promptInput, SIGNAL(redoPressed()), this, SIGNAL(redoPressed())); connect(promptInput, SIGNAL(shiftPressed()), this, SIGNAL(shiftPressed())); connect(promptInput, SIGNAL(shiftReleased()), this, SIGNAL(shiftReleased())); }
MainWindow::MainWindow() : QMainWindow(0) { readSettings(); QString lang = getSettingsGeneralLanguage(); qDebug("language: %s", qPrintable(lang)); if(lang == "system") lang = QLocale::system().languageToString(QLocale::system().language()).toLower(); //Load translations for the Embroidermodder 2 GUI QTranslator translatorEmb; translatorEmb.load("translations/" + lang + "/embroidermodder2_" + lang); qApp->installTranslator(&translatorEmb); //Load translations for the commands QTranslator translatorCmd; translatorCmd.load("translations/" + lang + "/commands_" + lang); qApp->installTranslator(&translatorCmd); //Load translations provided by Qt - this covers dialog buttons and other common things. QTranslator translatorQt; translatorQt.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); qApp->installTranslator(&translatorQt); //Init mainWin = this; //Menus fileMenu = new QMenu(tr("&File"), this); editMenu = new QMenu(tr("&Edit"), this); viewMenu = new QMenu(tr("&View"), this); settingsMenu = new QMenu(tr("&Settings"), this); windowMenu = new QMenu(tr("&Window"), this); helpMenu = new QMenu(tr("&Help"), this); //SubMenus recentMenu = new QMenu(tr("Open &Recent"), this); zoomMenu = new QMenu(tr("&Zoom"), this); panMenu = new QMenu(tr("&Pan"), this); //Toolbars toolbarFile = addToolBar(tr("File")); toolbarEdit = addToolBar(tr("Edit")); toolbarView = addToolBar(tr("View")); toolbarZoom = addToolBar(tr("Zoom")); toolbarPan = addToolBar(tr("Pan")); toolbarIcon = addToolBar(tr("Icon")); toolbarHelp = addToolBar(tr("Help")); toolbarLayer = addToolBar(tr("Layer")); toolbarProperties = addToolBar(tr("Properties")); toolbarText = addToolBar(tr("Text")); toolbarPrompt = addToolBar(tr("Command Prompt")); //Selectors layerSelector = new QComboBox(this); colorSelector = new QComboBox(this); linetypeSelector = new QComboBox(this); lineweightSelector = new QComboBox(this); textFontSelector = new QFontComboBox(this); textSizeSelector = new QComboBox(this); numOfDocs = 0; docIndex = 0; shiftKeyPressedState = false; setWindowIcon(QIcon("icons/" + getSettingsGeneralIconTheme() + "/" + "app" + ".png")); //create the mdiArea QFrame* vbox = new QFrame(this); QVBoxLayout* layout = new QVBoxLayout(vbox); layout->setMargin(0); vbox->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); mdiArea = new MdiArea(this, vbox); mdiArea->useBackgroundLogo(getSettingsGeneralMdiBGUseLogo()); mdiArea->useBackgroundTexture(getSettingsGeneralMdiBGUseTexture()); mdiArea->useBackgroundColor(getSettingsGeneralMdiBGUseColor()); mdiArea->setBackgroundLogo(getSettingsGeneralMdiBGLogo()); mdiArea->setBackgroundTexture(getSettingsGeneralMdiBGTexture()); mdiArea->setBackgroundColor(QColor(getSettingsGeneralMdiBGColor())); mdiArea->setViewMode(QMdiArea::TabbedView); mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); mdiArea->setActivationOrder(QMdiArea::ActivationHistoryOrder); layout->addWidget(mdiArea); setCentralWidget(vbox); //create the Command Prompt prompt = new CmdPrompt(this); prompt->setFocus(Qt::OtherFocusReason); this->setFocusProxy(prompt); mdiArea->setFocusProxy(prompt); prompt->setPromptTextColor(QColor(getSettingsPromptTextColor())); prompt->setPromptBackgroundColor(QColor(getSettingsPromptBGColor())); connect(prompt, SIGNAL(startCommand(const QString&)), this, SLOT(runCommandMain(const QString&))); connect(prompt, SIGNAL(runCommand(const QString&, const QString&)), this, SLOT(runCommandPrompt(const QString&, const QString&))); connect(prompt, SIGNAL(deletePressed()), this, SLOT(deletePressed())); //TODO: connect(prompt, SIGNAL(tabPressed()), this, SLOT(someUnknownSlot())); connect(prompt, SIGNAL(escapePressed()), this, SLOT(escapePressed())); connect(prompt, SIGNAL(F1Pressed()), this, SLOT(help())); //TODO: connect(prompt, SIGNAL(F2Pressed()), this, SLOT(floatHistory())); //TODO: connect(prompt, SIGNAL(F3Pressed()), this, SLOT(toggleQSNAP())); connect(prompt, SIGNAL(F4Pressed()), this, SLOT(toggleLwt())); //TODO: typically this is toggleTablet(), make F-Keys customizable thru settings //TODO: connect(prompt, SIGNAL(F5Pressed()), this, SLOT(toggleISO())); //TODO: connect(prompt, SIGNAL(F6Pressed()), this, SLOT(toggleCoords())); connect(prompt, SIGNAL(F7Pressed()), this, SLOT(toggleGrid())); //TODO: connect(prompt, SIGNAL(F8Pressed()), this, SLOT(toggleORTHO())); //TODO: connect(prompt, SIGNAL(F9Pressed()), this, SLOT(toggleSNAP())); //TODO: connect(prompt, SIGNAL(F10Pressed()), this, SLOT(togglePOLAR())); //TODO: connect(prompt, SIGNAL(F11Pressed()), this, SLOT(toggleQTRACK())); connect(prompt, SIGNAL(F12Pressed()), this, SLOT(toggleRuler())); connect(prompt, SIGNAL(cutPressed()), this, SLOT(cut())); connect(prompt, SIGNAL(copyPressed()), this, SLOT(copy())); connect(prompt, SIGNAL(pastePressed()), this, SLOT(paste())); connect(prompt, SIGNAL(selectAllPressed()), this, SLOT(selectAll())); connect(prompt, SIGNAL(undoPressed()), this, SLOT(undo())); connect(prompt, SIGNAL(redoPressed()), this, SLOT(redo())); connect(prompt, SIGNAL(shiftPressed()), this, SLOT(setShiftPressed())); connect(prompt, SIGNAL(shiftReleased()), this, SLOT(setShiftReleased())); //create the Object Property Editor dockPropEdit = new PropertyEditor("icons/" + getSettingsGeneralIconTheme(), getSettingsSelectionModePickAdd(), prompt, this); addDockWidget(Qt::LeftDockWidgetArea, dockPropEdit); connect(dockPropEdit, SIGNAL(pickAddModeToggled()), this, SLOT(pickAddModeToggled())); //create the Command History Undo Editor dockUndoEdit = new UndoEditor("icons/" + getSettingsGeneralIconTheme(), prompt, this); addDockWidget(Qt::LeftDockWidgetArea, dockUndoEdit); //setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowTabbedDocks | QMainWindow::VerticalTabs); //TODO: Load these from settings //tabifyDockWidget(dockPropEdit, dockUndoEdit); //TODO: load this from settings //Javascript initMainWinPointer(this); engine = new QScriptEngine(this); engine->installTranslatorFunctions(); debugger = new QScriptEngineDebugger(this); debugger->attachTo(engine); javaInitNatives(engine); //Load all commands in a loop QDir commandDir("commands"); QStringList cmdList = commandDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); foreach(QString cmdName, cmdList) { javaLoadCommand(cmdName); }