Ticket #6322: gridedit.trunk.code.2.patch
File gridedit.trunk.code.2.patch, 89.2 KB (added by , 16 years ago) |
---|
-
mythtv/libs/libmyth/mythdialogs.cpp
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmyth/mythdialogs.cpp myth.20136.0308b/mythtv/libs/libmyth/mythdialogs.cpp
1327 1327 rect_to_update = this->geometry(); 1328 1328 } 1329 1329 1330 redrawRect = redrawRect.unite(r );1330 redrawRect = redrawRect.unite(rect_to_update); 1331 1331 1332 1332 update(redrawRect); 1333 1333 } … … 1652 1652 return GetUIType<UIBlackHoleType>(this, name); 1653 1653 } 1654 1654 1655 UIGridEditImageType* MythThemedDialog::getUIGridEditImageType(const QString &name) 1656 { 1657 return GetUIType<UIGridEditImageType>(this, name); 1658 } 1659 1660 UIGridEditSliderType* MythThemedDialog::getUIGridEditSliderType(const QString &name) 1661 { 1662 return GetUIType<UIGridEditSliderType>(this, name); 1663 } 1664 1655 1665 UIImageType* MythThemedDialog::getUIImageType(const QString &name) 1656 1666 { 1657 1667 return GetUIType<UIImageType>(this, name); -
mythtv/libs/libmyth/mythdialogs.h
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmyth/mythdialogs.h myth.20136.0308b/mythtv/libs/libmyth/mythdialogs.h
26 26 class UICheckBoxType; 27 27 class UISelectorType; 28 28 class UIBlackHoleType; 29 class UIGridEditImageType; 30 class UIGridEditSliderType; 29 31 class UIImageType; 30 32 class UIImageGridType; 31 33 class UIStatusBarType; … … 373 375 UICheckBoxType *getUICheckBoxType(const QString &name); 374 376 UISelectorType *getUISelectorType(const QString &name); 375 377 UIBlackHoleType *getUIBlackHoleType(const QString &name); 378 UIGridEditImageType *getUIGridEditImageType(const QString &name); 379 UIGridEditSliderType *getUIGridEditSliderType(const QString &name); 376 380 UIImageGridType *getUIImageGridType(const QString &name); 377 381 UIImageType *getUIImageType(const QString &name); 378 382 UIStatusBarType *getUIStatusBarType(const QString &name); -
mythtv/libs/libmyth/uitypes.cpp
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmyth/uitypes.cpp myth.20136.0308b/mythtv/libs/libmyth/uitypes.cpp
4683 4683 4684 4684 // ******************************************************************** 4685 4685 4686 UIGridEditImageType::UIGridEditImageType(const QString &name) 4687 : UIType(name) 4688 { 4689 cutStatus = 0; 4690 framenumber = -1; 4691 } 4692 4693 void UIGridEditImageType::calculateScreenArea() 4694 { 4695 QRect r = area; 4696 r.translate(m_parent->GetAreaRect().left(), 4697 m_parent->GetAreaRect().top()); 4698 screen_area = r; 4699 4700 inner_border.setLeft(screen_area.left()+1); 4701 inner_border.setRight(screen_area.right()-1); 4702 inner_border.setTop(screen_area.top()+1); 4703 inner_border.setBottom(screen_area.bottom()-1); 4704 4705 outer_border.setLeft(screen_area.left()-1); 4706 outer_border.setRight(screen_area.right()+1); 4707 outer_border.setTop(screen_area.top()-1); 4708 outer_border.setBottom(screen_area.bottom()+1); 4709 } 4710 4711 void UIGridEditImageType::Draw(QPainter *p, int drawlayer, int context) 4712 { 4713 if (pmap.isNull()) 4714 { 4715 QColor drawcolor = QColor( 0, 0, 0); 4716 p->setBrush(QBrush(Qt::SolidPattern)); 4717 p->setPen(QPen(drawcolor, 2)); 4718 p->drawRect(screen_area); 4719 } 4720 else 4721 { 4722 p->drawPixmap(screen_area, pmap); 4723 4724 p->setBrush(QBrush(Qt::NoBrush)); 4725 p->setPen(QPen(colorSet[cutStatus], 3)); 4726 p->drawRect(inner_border); 4727 if (cutStatus > 0) { 4728 p->drawLine(inner_border.topLeft(), inner_border.bottomRight()); 4729 p->drawLine(inner_border.bottomLeft(), inner_border.topRight()); 4730 } 4731 } 4732 } 4733 4734 void UIGridEditImageType::setPixmap(QPixmap *new_pmap, long long frame, int new_cutStatus) 4735 { 4736 // We can get a null new_pmap at the start or end of the video 4737 if (! new_pmap) 4738 { 4739 clearPixmap(); 4740 return; 4741 } 4742 4743 if (frame == framenumber) 4744 { 4745 // No change in pixmap (?) 4746 setCutStatus(new_cutStatus); 4747 return; 4748 } 4749 4750 pmap = *new_pmap; 4751 framenumber = frame; 4752 4753 if (new_cutStatus >= 0 && new_cutStatus <= 3) 4754 cutStatus = new_cutStatus; 4755 else 4756 cutStatus = 0; 4757 4758 refresh(); 4759 } 4760 4761 void UIGridEditImageType::clearPixmap(bool dorefresh) 4762 { 4763 if (! pmap.isNull()) 4764 { 4765 pmap = QPixmap(); 4766 4767 cutStatus = 0; 4768 framenumber = -1; 4769 if (dorefresh) 4770 refresh(); 4771 } 4772 } 4773 4774 void UIGridEditImageType::setCutStatus(int new_cutStatus) 4775 { 4776 if (new_cutStatus == cutStatus) 4777 return; 4778 4779 if (new_cutStatus >= 0 && new_cutStatus <= 3) 4780 cutStatus = new_cutStatus; 4781 else 4782 cutStatus = 0; 4783 4784 refresh(); 4785 } 4786 4787 // ******************************************************************** 4788 4789 UIGridEditSliderType::UIGridEditSliderType(const QString &name) 4790 : UIType(name) 4791 { 4792 m_drawMap = NULL; 4793 m_position=0; 4794 } 4795 4796 void UIGridEditSliderType::calculateScreenArea() 4797 { 4798 QRect r = area; 4799 r.translate(m_parent->GetAreaRect().left(), 4800 m_parent->GetAreaRect().top()); 4801 screen_area = r; 4802 4803 if (m_drawMap) 4804 delete [] m_drawMap; 4805 4806 m_drawWidth = area.width(); 4807 m_drawMap = new unsigned char[m_drawWidth]; 4808 for (int i = 0; i < m_drawWidth; i++) 4809 m_drawMap[i] = 0; 4810 } 4811 4812 void UIGridEditSliderType::ClearAll() 4813 { 4814 for (int i = 0; i < m_drawWidth; i++) 4815 m_drawMap[i] = 0; 4816 refresh(); 4817 } 4818 4819 void UIGridEditSliderType::SetRange( 4820 long long fstart, long long fend, long long fcount) 4821 { 4822 if (fcount <= 0) 4823 { 4824 VERBOSE(VB_IMPORTANT, QString("Invalid frame count: %1") 4825 .arg(fcount)); 4826 return; 4827 } 4828 if (fstart < 0) 4829 { 4830 VERBOSE(VB_IMPORTANT, QString("Invalid starting frame: %1") 4831 .arg(fstart)); 4832 return; 4833 } 4834 if (fend < 0) 4835 { 4836 VERBOSE(VB_IMPORTANT, QString("Invalid ending frame: %1") 4837 .arg(fend)); 4838 return; 4839 } 4840 4841 if (fstart > fcount) fstart = fcount; 4842 if (fend > fcount) fend = fcount; 4843 4844 int start = (int)((1.0 * fstart * m_drawWidth) / fcount); 4845 int end = (int)((1.0 * fend * m_drawWidth) / fcount); 4846 4847 if (start < 0) 4848 start = 0; 4849 if (start >= m_drawWidth) 4850 start = m_drawWidth - 1; 4851 if (end < 0) 4852 end = 0; 4853 if (end >= m_drawWidth) 4854 end = m_drawWidth - 1; 4855 4856 if (end < start) 4857 { 4858 int tmp = start; 4859 start = end; 4860 end = tmp; 4861 } 4862 4863 for (int i = start; i < end; i++) 4864 if (m_drawMap[i] < 1) 4865 m_drawMap[i] = 1; 4866 4867 // Mark endpoints 4868 m_drawMap[start] = 2; 4869 m_drawMap[end] = 2; 4870 4871 VERBOSE(VB_GENERAL, QString("Range = %1 - %2 (%3 - %4)") 4872 .arg(start).arg(end) 4873 .arg(fstart).arg(fend)); 4874 refresh(); 4875 } 4876 4877 void UIGridEditSliderType::SetPosition( 4878 long long fposition, long long fcount) 4879 { 4880 if (fcount <= 0) 4881 { 4882 VERBOSE(VB_IMPORTANT, QString("Invalid frame count: %1") 4883 .arg(fcount)); 4884 return; 4885 } 4886 4887 if (fposition < 0) 4888 { 4889 VERBOSE(VB_IMPORTANT, QString("Invalid position frame: %1") 4890 .arg(fposition)); 4891 return; 4892 } 4893 4894 if (fposition > fcount) fposition = fcount; 4895 4896 int new_position = (int)(1.0 * fposition * m_drawWidth) / fcount; 4897 4898 if (new_position < 0) 4899 new_position = 0; 4900 if (new_position >= m_drawWidth) 4901 new_position = m_drawWidth - 1; 4902 4903 if (new_position != m_position) 4904 { 4905 m_position = new_position; 4906 refresh(); 4907 } 4908 } 4909 4910 void UIGridEditSliderType::Draw(QPainter *p, int drawlayer, int context) 4911 { 4912 // Draw Background 4913 p->setPen(QPen(colorSet[0], 2)); 4914 p->setBrush(colorSet[0]); 4915 p->drawRect(screen_area); 4916 4917 // Draw bars 4918 4919 // VERBOSE(VB_GENERAL, QString("Starting")); 4920 int i = 0; 4921 do { 4922 int start = 0; 4923 int end = 0; 4924 4925 while (i < m_drawWidth && m_drawMap[i] == 0) i++; 4926 if (i == m_drawWidth) break; 4927 start = i; 4928 4929 i++; 4930 4931 4932 while (i < m_drawWidth && m_drawMap[i] == 1) i++; 4933 end = i; 4934 if (end == m_drawWidth) end--; 4935 4936 // If the next map value is not a normal internal cutpoint 4937 // increment i so we handle it properly 4938 if (end+1 < m_drawWidth && m_drawMap[end+1] != 1) 4939 i++; 4940 4941 // start == starting point 4942 // end == endingpoint 4943 { 4944 QRect r = screen_area; 4945 r.setLeft(r.left() + start); 4946 r.setWidth(end - start); 4947 4948 // VERBOSE(VB_GENERAL, QString("Cut from (%1, %2) - (%3, %4)") 4949 // .arg(r.left()).arg(r.top()) 4950 // .arg(r.right()).arg(r.bottom())); 4951 4952 // VERBOSE(VB_GENERAL, QString("start = %1, m_position = %2, end = %3") 4953 // .arg(start) 4954 // .arg(m_position) 4955 // .arg(end)); 4956 4957 if (start <= m_position && m_position <= end) 4958 { 4959 p->setPen(QPen(colorSet[4], 2)); 4960 p->setBrush(colorSet[4]); 4961 } 4962 else 4963 { 4964 p->setPen(QPen(colorSet[1], 2)); 4965 p->setBrush(colorSet[1]); 4966 } 4967 p->drawRect(r); 4968 4969 p->setPen(QPen(colorSet[2], 2)); 4970 p->setBrush(colorSet[2]); 4971 if (m_drawMap[start] == 2) 4972 p->drawLine(r.topLeft(), r.bottomLeft()); 4973 if (m_drawMap[end] == 2) 4974 p->drawLine(r.topRight(), r.bottomRight()); 4975 4976 } 4977 } while (i < m_drawWidth); 4978 4979 // Draw Current Position Mark 4980 4981 QPoint ptop(screen_area.left() + m_position, screen_area.top()); 4982 QPoint pbot(screen_area.left() + m_position, screen_area.bottom()); 4983 4984 p->setPen(QPen(colorSet[3], 2)); 4985 p->setBrush(colorSet[3]); 4986 p->drawLine(ptop, pbot); 4987 } 4988 4989 // ******************************************************************** 4990 4686 4991 UIKeyType::UIKeyType(const QString &name) 4687 4992 : UIType(name) 4688 4993 { -
mythtv/libs/libmyth/uitypes.h
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmyth/uitypes.h myth.20136.0308b/mythtv/libs/libmyth/uitypes.h
1172 1172 QRect area; 1173 1173 }; 1174 1174 1175 class MPUBLIC UIGridEditImageType : public UIType 1176 { 1177 Q_OBJECT 1178 1179 public: 1180 1181 UIGridEditImageType(const QString &name); 1182 void calculateScreenArea(); 1183 void setArea(QRect an_area) { area = an_area; }; 1184 1185 void setOutlineColor(QColor c) { colorSet[0] = c; }; 1186 void setCutColor(QColor c) { colorSet[1] = c; }; 1187 void setCutPointColor(QColor c) 1188 { 1189 colorSet[2] = c; // Cut before 1190 colorSet[3] = c; // Cut after 1191 }; 1192 1193 virtual void Draw(QPainter *, int, int); 1194 void setPixmap(QPixmap *new_pmap, long long frame, int new_cutStatus); 1195 1196 void clearPixmap(bool dorefresh=true); 1197 void setCutStatus(int new_cutStatus); 1198 1199 QRect getOuterBorder() { return outer_border; }; 1200 protected: 1201 1202 QRect area; 1203 QRect inner_border; 1204 QRect outer_border; 1205 QPixmap pmap; 1206 long long framenumber; // for consistency checking 1207 int cutStatus; 1208 QColor colorSet[4]; 1209 }; 1210 1211 class MPUBLIC UIGridEditSliderType : public UIType 1212 { 1213 Q_OBJECT 1214 1215 public: 1216 1217 UIGridEditSliderType(const QString &name); 1218 void calculateScreenArea(); 1219 void setArea(QRect an_area) { area = an_area; }; 1220 1221 void setFillColor(QColor c) { colorSet[0] = c; }; 1222 void setCutColor(QColor c) { colorSet[1] = c; }; 1223 void setCutPointColor(QColor c) { colorSet[2] = c; }; 1224 void setPositionColor(QColor c) { colorSet[3] = c; }; 1225 void setInCutColor(QColor c) { colorSet[4] = c; }; 1226 1227 void ClearAll(); 1228 void SetRange(long long fstart, long long fend, long long fcount); 1229 void SetPosition(long long fposition, long long fcount); 1230 1231 virtual void Draw(QPainter *, int, int); 1232 protected: 1233 1234 QRect area; 1235 unsigned char *m_drawMap; 1236 int m_drawWidth; 1237 int m_position; 1238 1239 QColor colorSet[5]; 1240 }; 1241 1242 1175 1243 class MPUBLIC UIKeyType : public UIType 1176 1244 { 1177 1245 Q_OBJECT -
mythtv/libs/libmyth/xmlparse.cpp
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmyth/xmlparse.cpp myth.20136.0308b/mythtv/libs/libmyth/xmlparse.cpp
1363 1363 { 1364 1364 parseBlackHole(container, info); 1365 1365 } 1366 else if (info.tagName() == "grideditimage") 1367 { 1368 parseGridEditImage(container, info); 1369 } 1370 else if (info.tagName() == "grideditslider") 1371 { 1372 parseGridEditSlider(container, info); 1373 } 1366 1374 else if (info.tagName() == "area") 1367 1375 { 1368 1376 area = parseRect(getFirstText(info)); … … 3126 3134 container->AddType(bh); 3127 3135 } 3128 3136 3137 3138 void XMLParse::parseGridEditImage(LayerSet *container, QDomElement &element) 3139 { 3140 QRect area; 3141 QColor outlineColor; 3142 QColor cutColor; 3143 QColor cutPointColor; 3144 bool haveOutlineColor = false; 3145 bool haveCutColor = false; 3146 bool haveCutPointColor = false; 3147 3148 QString name = element.attribute("name", ""); 3149 if (name.isNull() || name.isEmpty()) 3150 { 3151 VERBOSE(VB_IMPORTANT, LOC_WARN + "GridEditImage needs a name"); 3152 return; 3153 } 3154 3155 for (QDomNode child = element.firstChild(); !child.isNull(); 3156 child = child.nextSibling()) 3157 { 3158 QDomElement info = child.toElement(); 3159 if (!info.isNull()) 3160 { 3161 if (info.tagName() == "area") 3162 { 3163 area = parseRect(getFirstText(info)); 3164 normalizeRect(area); 3165 } 3166 else if (info.tagName() == "outlinecolor") 3167 { 3168 haveOutlineColor = true; 3169 outlineColor = getFirstText(info); 3170 } 3171 else if (info.tagName() == "cutcolor") 3172 { 3173 haveCutColor = true; 3174 cutColor = getFirstText(info); 3175 } 3176 else if (info.tagName() == "cutpointcolor") 3177 { 3178 haveCutPointColor = true; 3179 cutPointColor = getFirstText(info); 3180 } 3181 else 3182 { 3183 VERBOSE(VB_IMPORTANT, LOC_WARN + 3184 QString("Unknown tag '%1' in grideditimage '%2'") 3185 .arg(info.tagName()).arg(name)); 3186 return; 3187 } 3188 } 3189 } 3190 3191 if (!haveOutlineColor) 3192 { 3193 VERBOSE(VB_IMPORTANT, LOC_WARN + 3194 QString("Missing tag 'outlinecolor' in grideditimage '%1'") 3195 .arg(name)); 3196 return; 3197 } 3198 3199 if (!haveCutColor) 3200 { 3201 VERBOSE(VB_IMPORTANT, LOC_WARN + 3202 QString("Missing tag 'cutcolor' in grideditimage '%1'") 3203 .arg(name)); 3204 return; 3205 } 3206 3207 if (!haveCutPointColor) 3208 { 3209 VERBOSE(VB_IMPORTANT, LOC_WARN + 3210 QString("Missing tag 'cutpointcolor' in grideditimage '%1'") 3211 .arg(name)); 3212 return; 3213 } 3214 3215 UIGridEditImageType *gei = new UIGridEditImageType(name); 3216 gei->SetScreen(wmult, hmult); 3217 gei->setArea(area); 3218 gei->setOutlineColor(outlineColor); 3219 gei->setCutColor(cutColor); 3220 gei->setCutPointColor(cutPointColor); 3221 gei->SetParent(container); 3222 gei->calculateScreenArea(); 3223 gei->clearPixmap(false); 3224 container->AddType(gei); 3225 } 3226 3227 void XMLParse::parseGridEditSlider(LayerSet *container, QDomElement &element) 3228 { 3229 QRect area; 3230 QColor fillColor; 3231 QColor cutColor; 3232 QColor inCutColor; 3233 QColor cutPointColor; 3234 QColor positionColor; 3235 bool haveFillColor = false; 3236 bool haveCutColor = false; 3237 bool haveInCutColor = false; 3238 bool haveCutPointColor = false; 3239 bool havePositionColor = false; 3240 3241 QString name = element.attribute("name", ""); 3242 if (name.isNull() || name.isEmpty()) 3243 { 3244 VERBOSE(VB_IMPORTANT, LOC_WARN + "GridEditSlider needs a name"); 3245 return; 3246 } 3247 3248 for (QDomNode child = element.firstChild(); !child.isNull(); 3249 child = child.nextSibling()) 3250 { 3251 QDomElement info = child.toElement(); 3252 if (!info.isNull()) 3253 { 3254 if (info.tagName() == "area") 3255 { 3256 area = parseRect(getFirstText(info)); 3257 normalizeRect(area); 3258 } 3259 else if (info.tagName() == "fillcolor") 3260 { 3261 haveFillColor = true; 3262 fillColor = getFirstText(info); 3263 } 3264 else if (info.tagName() == "cutcolor") 3265 { 3266 haveCutColor = true; 3267 cutColor = getFirstText(info); 3268 } 3269 else if (info.tagName() == "incutcolor") 3270 { 3271 haveInCutColor = true; 3272 inCutColor = getFirstText(info); 3273 } 3274 else if (info.tagName() == "cutpointcolor") 3275 { 3276 haveCutPointColor = true; 3277 cutPointColor = getFirstText(info); 3278 } 3279 else if (info.tagName() == "positioncolor") 3280 { 3281 havePositionColor = true; 3282 positionColor = getFirstText(info); 3283 } 3284 else 3285 { 3286 VERBOSE(VB_IMPORTANT, LOC_WARN + 3287 QString("Unknown tag '%1' in grideditslider '%2'") 3288 .arg(info.tagName()).arg(name)); 3289 return; 3290 } 3291 } 3292 } 3293 3294 if (!haveFillColor) 3295 { 3296 VERBOSE(VB_IMPORTANT, LOC_WARN + 3297 QString("Missing tag 'fillcolor' in grideditslider '%1'") 3298 .arg(name)); 3299 return; 3300 } 3301 3302 if (!haveCutColor) 3303 { 3304 VERBOSE(VB_IMPORTANT, LOC_WARN + 3305 QString("Missing tag 'cutcolor' in grideditslider '%1'") 3306 .arg(name)); 3307 return; 3308 } 3309 3310 if (!haveInCutColor) 3311 { 3312 VERBOSE(VB_IMPORTANT, LOC_WARN + 3313 QString("Missing tag 'incutcolor' in grideditslider '%1'") 3314 .arg(name)); 3315 return; 3316 } 3317 3318 if (!haveCutPointColor) 3319 { 3320 VERBOSE(VB_IMPORTANT, LOC_WARN + 3321 QString("Missing tag 'cutpointcolor' in grideditslider '%1'") 3322 .arg(name)); 3323 return; 3324 } 3325 3326 if (!havePositionColor) 3327 { 3328 VERBOSE(VB_IMPORTANT, LOC_WARN + 3329 QString("Missing tag 'positioncolor' in grideditslider '%1'") 3330 .arg(name)); 3331 return; 3332 } 3333 3334 UIGridEditSliderType *ges = new UIGridEditSliderType(name); 3335 ges->SetScreen(wmult, hmult); 3336 ges->setArea(area); 3337 ges->setFillColor(fillColor); 3338 ges->setCutColor(cutColor); 3339 ges->setInCutColor(inCutColor); 3340 ges->setCutPointColor(cutPointColor); 3341 ges->setPositionColor(positionColor); 3342 ges->SetParent(container); 3343 ges->calculateScreenArea(); 3344 container->AddType(ges); 3345 } 3346 3129 3347 void XMLParse::parseListBtnArea(LayerSet *container, QDomElement &element) 3130 3348 { 3131 3349 int context = -1; -
mythtv/libs/libmyth/xmlparse.h
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmyth/xmlparse.h myth.20136.0308b/mythtv/libs/libmyth/xmlparse.h
47 47 void parseCheckBox(LayerSet *, QDomElement &); 48 48 void parseSelector(LayerSet *, QDomElement &); 49 49 void parseBlackHole(LayerSet *, QDomElement &); 50 void parseGridEditImage(LayerSet *, QDomElement &); 51 void parseGridEditSlider(LayerSet *, QDomElement &); 50 52 void parseListBtnArea(LayerSet *, QDomElement &); 51 53 void parseListTreeArea(LayerSet *, QDomElement &); 52 54 void parseKeyboard(LayerSet *, QDomElement &); -
mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp myth.20136.0308b/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
55 55 #include "mythverbose.h" 56 56 #include "myth_imgconvert.h" 57 57 58 #include "grideditcutpoints.h" 59 58 60 extern "C" { 59 61 #include "vbitext/vbi.h" 60 62 #include "vsync.h" … … 166 168 decoder_thread_alive(true), killplayer(false), 167 169 killvideo(false), livetv(false), 168 170 watchingrecording(false), editmode(false), 171 hideedits(false), 169 172 resetvideo(false), using_null_videoout(false), 170 173 no_audio_in(false), no_audio_out(false), 171 174 transcoding(false), … … 175 178 bookmarkseek(0), previewFromBookmark(false), 176 179 // Seek 177 180 fftime(0), seekamountpos(4), 178 seekamount(30), exactseeks(false), 181 allow_pagesize(false), half_page(0), 182 seekamount(30), seekamounttext("30 Frames"), 183 exactseeks(false), 179 184 // Playback misc. 180 185 videobuf_retries(0), framesPlayed(0), 181 186 totalFrames(0), totalLength(0), … … 225 230 yuv_need_copy(false), yuv_desired_size(0,0), 226 231 yuv_scaler(NULL), yuv_frame_scaled(NULL), 227 232 yuv_scaler_in_size(0,0), yuv_scaler_out_size(0,0), 233 // Grid Editing 234 grid_edit_image_buffer(NULL), grid_edit_image_buffer_length(0), 228 235 // Filters 229 236 videoFiltersForProgram(""), videoFiltersOverride(""), 230 237 postfilt_width(0), postfilt_height(0), … … 371 378 output_jmeter = NULL; 372 379 } 373 380 381 if (grid_edit_image_buffer) 382 { 383 delete [] grid_edit_image_buffer; 384 grid_edit_image_buffer = NULL; 385 grid_edit_image_buffer_length=0; 386 } 387 374 388 ShutdownYUVResize(); 375 389 } 376 390 … … 1605 1619 return retval; 1606 1620 } 1607 1621 1622 1623 QImage NuppelVideoPlayer::GetScreenGrabOfCurrentFrame(QSize size) 1624 { 1625 1626 unsigned char *data = NULL; 1627 VideoFrame *frame = NULL; 1628 AVPicture orig; 1629 AVPicture retbuf; 1630 bzero(&orig, sizeof(AVPicture)); 1631 bzero(&retbuf, sizeof(AVPicture)); 1632 1633 QImage edit_scaled_img; 1634 int vw, vh; 1635 if (!(frame = GetCurrentFrame(vw, vh))) 1636 { 1637 return edit_scaled_img; 1638 } 1639 1640 if (!(data = frame->buf)) 1641 { 1642 ReleaseCurrentFrame(frame); 1643 return edit_scaled_img; 1644 } 1645 1646 avpicture_fill(&orig, data, PIX_FMT_YUV420P, 1647 video_dim.width(), video_dim.height()); 1648 1649 avpicture_deinterlace(&orig, &orig, PIX_FMT_YUV420P, 1650 video_dim.width(), video_dim.height()); 1651 1652 int bufflen = video_dim.width() * video_dim.height() * 4; 1653 if (!grid_edit_image_buffer) 1654 { 1655 grid_edit_image_buffer = new unsigned char[bufflen]; 1656 grid_edit_image_buffer_length = bufflen; 1657 } 1658 else if (bufflen > grid_edit_image_buffer_length) 1659 { 1660 delete [] grid_edit_image_buffer; 1661 grid_edit_image_buffer = new unsigned char[bufflen]; 1662 grid_edit_image_buffer_length = bufflen; 1663 } 1664 1665 // Connect outputbuf to retbuf 1666 avpicture_fill(&retbuf, grid_edit_image_buffer, PIX_FMT_RGBA32, 1667 video_dim.width(), video_dim.height()); 1668 1669 // convert from orig into retbuf(grid_edit_image_buffer) 1670 img_convert(&retbuf, PIX_FMT_RGBA32, &orig, PIX_FMT_YUV420P, 1671 video_dim.width(), video_dim.height()); 1672 1673 QImage tmpimage = QImage(grid_edit_image_buffer, video_dim.width(), video_dim.height(), 1674 QImage::Format_RGB32); 1675 1676 ReleaseCurrentFrame(frame); 1677 1678 edit_scaled_img = tmpimage.scaled(size, Qt::KeepAspectRatio).rgbSwapped(); 1679 1680 return edit_scaled_img; 1681 } 1682 1608 1683 void NuppelVideoPlayer::ReleaseCurrentFrame(VideoFrame *frame) 1609 1684 { 1610 1685 if (frame) … … 4988 5063 4989 5064 dialogname = ""; 4990 5065 5066 osd->HideAllExcept("editmode"); 5067 4991 5068 QMap<QString, QString> infoMap; 4992 5069 player_ctx->LockPlayingInfo(__FILE__, __LINE__); 4993 5070 player_ctx->playingInfo->ToMap(infoMap); … … 5052 5129 player_ctx->UnlockPlayingInfo(__FILE__, __LINE__); 5053 5130 } 5054 5131 5132 bool NuppelVideoPlayer::EditSeekToFrame(long long targetFrame) 5133 { 5134 bool tmpexactseeks = exactseeks; 5135 GetDecoder()->setExactSeeks(true); 5136 5137 // VERBOSE(VB_GENERAL, QString("Before current frame = %1, going to frame %2") 5138 // .arg(GetFramesPlayed()) 5139 // .arg(targetFrame)); 5140 5141 if (framesPlayed > targetFrame) 5142 { 5143 // seek back 5144 rewindtime = framesPlayed - targetFrame; 5145 while (rewindtime != 0) 5146 usleep(1000); 5147 } 5148 else 5149 { 5150 // seek forward 5151 fftime = targetFrame - framesPlayed; 5152 while (fftime != 0) 5153 usleep(1000); 5154 5155 } 5156 // VERBOSE(VB_GENERAL, QString("After current frame = %1") 5157 // .arg(GetFramesPlayed())); 5158 GetDecoder()->setExactSeeks(tmpexactseeks); 5159 return (targetFrame == framesPlayed); 5160 } 5161 5162 void NuppelVideoPlayer::EditHandleClearMap() 5163 { 5164 QMap<long long, int>::Iterator it; 5165 for (it = deleteMap.begin(); it != deleteMap.end(); ++it) 5166 osd->HideEditArrow(it.key(), *it); 5167 5168 deleteMap.clear(); 5169 UpdateEditSlider(); 5170 } 5171 5172 void NuppelVideoPlayer::EditHandleInvertMap() 5173 { 5174 QMap<long long, int>::Iterator it; 5175 for (it = deleteMap.begin(); it != deleteMap.end(); ++it) 5176 ReverseMark(it.key()); 5177 5178 UpdateEditSlider(); 5179 UpdateTimeDisplay(); 5180 } 5181 5182 void NuppelVideoPlayer::EditHandleLoadCommSkip() 5183 { 5184 if (hascommbreaktable) 5185 { 5186 commBreakMapLock.lock(); 5187 QMap<long long, int>::Iterator it; 5188 for (it = commBreakMap.begin(); it != commBreakMap.end(); ++it) 5189 { 5190 if (!deleteMap.contains(it.key())) 5191 { 5192 if (*it == MARK_COMM_START) 5193 AddMark(it.key(), MARK_CUT_START); 5194 else 5195 AddMark(it.key(), MARK_CUT_END); 5196 } 5197 } 5198 commBreakMapLock.unlock(); 5199 UpdateEditSlider(); 5200 UpdateTimeDisplay(); 5201 } 5202 } 5203 5055 5204 bool NuppelVideoPlayer::DoKeypress(QKeyEvent *e) 5056 5205 { 5057 5206 bool handled = false; … … 5131 5280 UpdateTimeDisplay(); 5132 5281 } 5133 5282 else if (action == "CLEARMAP") 5134 { 5135 QMap<long long, int>::Iterator it; 5136 for (it = deleteMap.begin(); it != deleteMap.end(); ++it) 5137 osd->HideEditArrow(it.key(), *it); 5138 5139 deleteMap.clear(); 5140 UpdateEditSlider(); 5141 } 5283 EditHandleClearMap(); 5142 5284 else if (action == "INVERTMAP") 5143 { 5144 QMap<long long, int>::Iterator it; 5145 for (it = deleteMap.begin(); it != deleteMap.end(); ++it) 5146 ReverseMark(it.key()); 5147 5148 UpdateEditSlider(); 5149 UpdateTimeDisplay(); 5150 } 5285 EditHandleInvertMap(); 5151 5286 else if (action == "LOADCOMMSKIP") 5152 { 5153 if (hascommbreaktable) 5154 { 5155 commBreakMapLock.lock(); 5156 QMap<long long, int>::Iterator it; 5157 for (it = commBreakMap.begin(); it != commBreakMap.end(); ++it) 5158 { 5159 if (!deleteMap.contains(it.key())) 5160 { 5161 if (*it == MARK_COMM_START) 5162 AddMark(it.key(), MARK_CUT_START); 5163 else 5164 AddMark(it.key(), MARK_CUT_END); 5165 } 5166 } 5167 commBreakMapLock.unlock(); 5168 UpdateEditSlider(); 5169 UpdateTimeDisplay(); 5170 } 5171 } 5287 EditHandleLoadCommSkip(); 5172 5288 else if (action == "PREVCUT") 5173 5289 { 5174 5290 int old_seekamount = seekamount; … … 5214 5330 UpdateEditSlider(); 5215 5331 UpdateTimeDisplay(); 5216 5332 } 5217 else if (action == "ESCAPE" || action == "MENU" || 5218 action == "TOGGLEEDIT") 5333 else if (action == "TOGGLEEDIT" || action == "MENU") 5334 m_tv->ShowEditRecordingGrid(); 5335 else if (action == "ESCAPE") 5219 5336 { 5220 5337 DisableEdit(); 5221 5338 retval = false; … … 5228 5345 return retval; 5229 5346 } 5230 5347 5348 void NuppelVideoPlayer::ShowEditRecordingGrid(void) 5349 { 5350 // Completely hide the OSD 5351 osd->HideAll(); 5352 hideedits = true; 5353 5354 GridEditCutpoints::Run(this); 5355 5356 if (grid_edit_image_buffer) 5357 { 5358 delete [] grid_edit_image_buffer; 5359 grid_edit_image_buffer = NULL; 5360 grid_edit_image_buffer_length = 0; 5361 } 5362 5363 allow_pagesize = false; 5364 hideedits = false; 5365 5366 // Show OSD 5367 5368 QMap<QString, QString> infoMap; 5369 player_ctx->LockPlayingInfo(__FILE__, __LINE__); 5370 player_ctx->playingInfo->ToMap(infoMap); 5371 infoMap.detach(); 5372 player_ctx->UnlockPlayingInfo(__FILE__, __LINE__); 5373 5374 osd->SetText("editmode", infoMap, -1); 5375 5376 UpdateEditSlider(); 5377 UpdateTimeDisplay(); 5378 if (seekamountpos == 3 || seekamountpos == 4) 5379 UpdateSeekAmount(true); 5380 else 5381 UpdateSeekAmountDisplay(); 5382 5383 QMap<long long, int>::Iterator it; 5384 for (it = deleteMap.begin(); it != deleteMap.end(); ++it) 5385 AddMark(it.key(), *it); 5386 } 5387 5231 5388 AspectOverrideMode NuppelVideoPlayer::GetAspectOverride(void) const 5232 5389 { 5233 5390 if (videoOutput) … … 5304 5461 5305 5462 void NuppelVideoPlayer::UpdateSeekAmount(bool up) 5306 5463 { 5307 if (seekamountpos > 0 && !up) 5308 seekamountpos--; 5309 if (seekamountpos < 9 && up) 5310 seekamountpos++; 5464 if (up) 5465 { 5466 if (seekamountpos < 11) 5467 seekamountpos++; 5468 if (allow_pagesize) 5469 { 5470 if (seekamountpos == 1) 5471 seekamountpos = 2; 5472 } 5473 else 5474 { 5475 if (seekamountpos == 3 || seekamountpos == 4) 5476 seekamountpos = 5; 5477 } 5478 } 5479 else 5480 { 5481 if (seekamountpos > 0) 5482 seekamountpos--; 5483 if (allow_pagesize) 5484 { 5485 if (seekamountpos == 1) 5486 seekamountpos =0; 5487 } 5488 else 5489 { 5490 if (seekamountpos == 3 || seekamountpos == 4) 5491 seekamountpos = 2; 5492 } 5493 } 5311 5494 5312 5495 QString text = ""; 5313 5496 5314 5497 switch (seekamountpos) 5315 5498 { 5316 case 0: text = QObject::tr("cut point"); seekamount = -2; break; 5317 case 1: text = QObject::tr("keyframe"); seekamount = -1; break; 5318 case 2: text = QObject::tr("1 frame"); seekamount = 1; break; 5319 case 3: text = QObject::tr("0.5 seconds"); seekamount = (int)roundf(video_frame_rate / 2); break; 5320 case 4: text = QObject::tr("%n second(s)", "", 1); seekamount = (int)roundf(video_frame_rate); break; 5321 case 5: text = QObject::tr("%n second(s)", "", 5); seekamount = (int)roundf(video_frame_rate * 5); break; 5322 case 6: text = QObject::tr("%n second(s)", "", 20); seekamount = (int)roundf(video_frame_rate * 20); break; 5323 case 7: text = QObject::tr("%n minute(s)", "", 1); seekamount = (int)roundf(video_frame_rate * 60); break; 5324 case 8: text = QObject::tr("%n minute(s)", "", 5); seekamount = (int)roundf(video_frame_rate * 300); break; 5325 case 9: text = QObject::tr("%n minute(s)", "", 10); seekamount = (int)roundf(video_frame_rate * 600); break; 5499 case 0: text = QObject::tr("cut point"); seekamount = -2; break; 5500 5501 // Only for non-edit grid 5502 case 1: text = QObject::tr("keyframe"); seekamount = -1; break; 5503 // Only for non-edit grid 5504 5505 case 2: text = QObject::tr("1 frame"); seekamount = 1; break; 5506 5507 // Case 3 & 4 are for the edit grid only 5508 case 3: text = QObject::tr("1/2 Page"); seekamount = half_page; break; 5509 case 4: text = QObject::tr("Full Page"); seekamount = 2*half_page; break; 5510 // Case 3 & 4 are for the edit grid only 5511 5512 case 5: text = QObject::tr("0.5 seconds"); seekamount = (int)roundf(video_frame_rate / 2); break; 5513 case 6: text = QObject::tr("%n second(s)", "", 1); seekamount = (int)roundf(video_frame_rate); break; 5514 case 7: text = QObject::tr("%n second(s)", "", 5); seekamount = (int)roundf(video_frame_rate * 5); break; 5515 case 8: text = QObject::tr("%n second(s)", "", 20); seekamount = (int)roundf(video_frame_rate * 20); break; 5516 case 9: text = QObject::tr("%n minute(s)", "", 1); seekamount = (int)roundf(video_frame_rate * 60); break; 5517 case 10: text = QObject::tr("%n minute(s)", "", 5); seekamount = (int)roundf(video_frame_rate * 300); break; 5518 case 11: text = QObject::tr("%n minute(s)", "", 10); seekamount = (int)roundf(video_frame_rate * 600); break; 5326 5519 default: text = QObject::tr("error"); seekamount = (int)roundf(video_frame_rate); break; 5327 5520 } 5328 5521 5522 seekamounttext = text; 5523 UpdateSeekAmountDisplay(); 5524 } 5525 5526 void NuppelVideoPlayer::UpdateSeekAmountDisplay(void) 5527 { 5329 5528 QMap<QString, QString> infoMap; 5330 infoMap["seekamount"] = text; 5331 osd->SetText("editmode", infoMap, -1); 5529 infoMap["seekamount"] = seekamounttext; 5530 if (!hideedits) 5531 osd->SetText("editmode", infoMap, -1); 5332 5532 } 5333 5533 5334 5534 void NuppelVideoPlayer::UpdateTimeDisplay(void) … … 5358 5558 infoMap["timedisplay"] = timestr; 5359 5559 infoMap["framedisplay"] = framestr; 5360 5560 infoMap["cutindicator"] = cutmarker; 5361 osd->SetText("editmode", infoMap, -1); 5561 if (!hideedits) 5562 osd->SetText("editmode", infoMap, -1); 5362 5563 } 5363 5564 5364 5565 void NuppelVideoPlayer::HandleSelect(bool allowSelectNear) … … 5490 5691 5491 5692 void NuppelVideoPlayer::UpdateEditSlider(void) 5492 5693 { 5493 osd->DoEditSlider(deleteMap, framesPlayed, totalFrames); 5694 if (!hideedits) 5695 osd->DoEditSlider(deleteMap, framesPlayed, totalFrames); 5494 5696 } 5495 5697 5496 5698 void NuppelVideoPlayer::AddMark(long long frames, int type) 5497 5699 { 5498 5700 deleteMap[frames] = type; 5499 osd->ShowEditArrow(frames, totalFrames, type); 5701 if (!hideedits) 5702 osd->ShowEditArrow(frames, totalFrames, type); 5500 5703 } 5501 5704 5502 5705 void NuppelVideoPlayer::DeleteMark(long long frames) 5503 5706 { 5504 osd->HideEditArrow(frames, deleteMap[frames]); 5707 if (!hideedits) 5708 osd->HideEditArrow(frames, deleteMap[frames]); 5505 5709 deleteMap.remove(frames); 5506 5710 } 5507 5711 5508 5712 void NuppelVideoPlayer::ReverseMark(long long frames) 5509 5713 { 5510 osd->HideEditArrow(frames, deleteMap[frames]); 5714 if (!hideedits) 5715 osd->HideEditArrow(frames, deleteMap[frames]); 5511 5716 5512 5717 if (deleteMap[frames] == MARK_CUT_END) 5513 5718 deleteMap[frames] = MARK_CUT_START; 5514 5719 else 5515 5720 deleteMap[frames] = MARK_CUT_END; 5516 5721 5517 osd->ShowEditArrow(frames, totalFrames, deleteMap[frames]); 5722 if (!hideedits) 5723 osd->ShowEditArrow(frames, totalFrames, deleteMap[frames]); 5724 } 5725 5726 long long NuppelVideoPlayer::CalcCutPointSeek(long long baseframe, bool right) 5727 { 5728 QMap<long long, int>::Iterator i = deleteMap.begin(); 5729 long long framenum = -1; 5730 long long seekcount = 0; 5731 if (right) 5732 { 5733 for (; i != deleteMap.end(); ++i) 5734 { 5735 if (i.key() > baseframe) 5736 { 5737 framenum = i.key(); 5738 break; 5739 } 5740 } 5741 if (framenum == -1) 5742 framenum = totalFrames; 5743 seekcount = framenum - baseframe; 5744 } 5745 else 5746 { 5747 for (; i != deleteMap.end(); ++i) 5748 { 5749 if (i.key() >= baseframe) 5750 break; 5751 framenum = i.key(); 5752 } 5753 if (framenum == -1) 5754 framenum = 0; 5755 seekcount = baseframe - framenum; 5756 } 5757 return seekcount; 5518 5758 } 5519 5759 5520 5760 void NuppelVideoPlayer::HandleArbSeek(bool right) 5521 5761 { 5522 5762 if (seekamount == -2) 5523 5763 { 5524 QMap<long long, int>::Iterator i = deleteMap.begin(); 5525 long long framenum = -1; 5764 long long seekcount = CalcCutPointSeek(framesPlayed, right); 5526 5765 if (right) 5527 5766 { 5528 for (; i != deleteMap.end(); ++i) 5529 { 5530 if (i.key() > framesPlayed) 5531 { 5532 framenum = i.key(); 5533 break; 5534 } 5535 } 5536 if (framenum == -1) 5537 framenum = totalFrames; 5538 5539 fftime = framenum - framesPlayed; 5767 fftime = seekcount; 5540 5768 while (fftime > 0) 5541 5769 usleep(1000); 5542 5770 } 5543 5771 else 5544 5772 { 5545 for (; i != deleteMap.end(); ++i) 5546 { 5547 if (i.key() >= framesPlayed) 5548 break; 5549 framenum = i.key(); 5550 } 5551 if (framenum == -1) 5552 framenum = 0; 5553 5554 rewindtime = framesPlayed - framenum; 5773 rewindtime = seekcount; 5555 5774 while (rewindtime > 0) 5556 5775 usleep(1000); 5557 5776 } … … 5582 5801 UpdateEditSlider(); 5583 5802 } 5584 5803 5804 int NuppelVideoPlayer::GetCutStatus(long long testframe) const 5805 { 5806 int retval = 0; 5807 QMap<long long, int>::const_iterator i; 5808 i = deleteMap.find(testframe); 5809 if (i == deleteMap.end()) { 5810 // testframe is not an explicit cutpoint 5811 // See if it is in a deleted area 5812 if (IsInDelete(testframe)) 5813 retval = 1; 5814 } else { 5815 int direction = *i; 5816 if (direction == 0) 5817 retval = 2; 5818 else 5819 retval = 3; 5820 } 5821 5822 return retval; 5823 } 5824 5585 5825 bool NuppelVideoPlayer::IsInDelete(long long testframe) const 5586 5826 { 5587 5827 long long startpos = 0; -
mythtv/libs/libmythtv/NuppelVideoPlayer.h
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmythtv/NuppelVideoPlayer.h myth.20136.0308b/mythtv/libs/libmythtv/NuppelVideoPlayer.h
104 104 class MPUBLIC NuppelVideoPlayer : public CC608Reader, public CC708Reader 105 105 { 106 106 friend class PlayerContext; 107 friend class GridEditCutpoints; 108 friend class TV; 107 109 108 110 public: 109 111 NuppelVideoPlayer(); … … 282 284 bool EnableEdit(void); 283 285 bool DoKeypress(QKeyEvent *e); 284 286 bool GetEditMode(void) const { return editmode; } 287 bool GetHideEdits(void) const { return hideedits; } 285 288 286 289 // Decoder stuff.. 287 290 VideoFrame *GetNextVideoFrame(bool allow_unsafe = true); … … 301 304 void ShutdownYUVResize(void); 302 305 void SaveScreenshot(void); 303 306 307 // Edit stuff 308 bool EditSeekToFrame(long long targetFrame); 309 QImage GetScreenGrabOfCurrentFrame(QSize size); // Get current frame 310 311 void EditHandleClearMap(); 312 void EditHandleInvertMap(); 313 void EditHandleLoadCommSkip(); 314 315 void ShowEditRecordingGrid(); 316 304 317 // Reinit 305 318 void ReinitOSD(void); 306 319 void ReinitVideo(void); … … 420 433 bool PosMapFromEnc(unsigned long long start, 421 434 QMap<long long, long long> &posMap); 422 435 436 // Stuf for GridEditCutpoints 437 long long CalcCutPointSeek(long long baseframe, bool right); 438 // returns 439 // 0 - no cut 440 // 1 - is deleted 441 // 2 - cut left 442 // 3 - cut right 443 int GetCutStatus(long long testframe) const; 444 long long GetSeekAmount() { return seekamount; } 445 QString GetSeekAmountText() { return seekamounttext; } 446 423 447 protected: 424 448 void DisplayPauseFrame(void); 425 449 void DisplayNormalFrame(void); … … 503 527 void HandleResponse(void); 504 528 505 529 void UpdateTimeDisplay(void); 530 int GetSeekAmountPos() { return seekamountpos; } 506 531 void UpdateSeekAmount(bool up); 532 void SetHalfPageSize(int hp) { allow_pagesize = true; half_page = hp; } 533 void UpdateSeekAmountDisplay(void); 507 534 void UpdateEditSlider(void); 508 535 509 536 // Private A/V Sync Stuff … … 576 603 bool livetv; 577 604 bool watchingrecording; 578 605 bool editmode; 606 bool hideedits; 579 607 bool resetvideo; 580 608 bool using_null_videoout; 581 609 bool no_audio_in; … … 596 624 long long fftime; 597 625 /// 1..9 == keyframe..10 minutes. 0 == cut point 598 626 int seekamountpos; 627 /// Used for Grid Edit logic 628 bool allow_pagesize; 629 int half_page; 599 630 /// Seekable frame increment when not using exact seeks. 600 631 /// Usually equal to keyframedist. 601 632 int seekamount; 633 QString seekamounttext; // OSD seek units 602 634 /// Iff true we ignore seek amount and try to seek to an 603 635 /// exact frame ignoring key frame restrictions. 604 636 bool exactseeks; … … 737 769 QMutex yuv_lock; 738 770 QWaitCondition yuv_wait; 739 771 772 // EditGrid still image capture 773 unsigned char *grid_edit_image_buffer; 774 int grid_edit_image_buffer_length; 775 740 776 // Filters 741 777 QMutex videofiltersLock; 742 778 QString videoFiltersForProgram; -
mythtv/libs/libmythtv/grideditcutpoints.cpp
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmythtv/grideditcutpoints.cpp myth.20136.0308b/mythtv/libs/libmythtv/grideditcutpoints.cpp
1 #include <math.h> 2 #include <unistd.h> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 #include <QApplication> 8 #include <QPainter> 9 #include <QFont> 10 #include <QKeyEvent> 11 #include <QEvent> 12 #include <QPixmap> 13 #include <QPaintEvent> 14 #include <QCursor> 15 #include <QImage> 16 #include <QLayout> 17 #include <QLabel> 18 #include <QDateTime> 19 #include <QRect> 20 21 #include "mythcontext.h" 22 #include "mythdbcon.h" 23 #include "grideditcutpoints.h" 24 #include "grideditimages.h" 25 #include "NuppelVideoPlayer.h" 26 27 void GridEditCutpoints::Run(NuppelVideoPlayer *player) 28 { 29 VERBOSE(VB_GENERAL, "Starting"); 30 gContext->addCurrentLocation("GridEditCutpoints"); 31 32 GridEditCutpoints *er = new GridEditCutpoints(gContext->GetMainWindow(), 33 player, "editrecording"); 34 35 er->Show(); 36 er->displayInitialFrame(); 37 er->exec(); 38 39 delete er; 40 41 gContext->removeCurrentLocation(); 42 VERBOSE(VB_GENERAL, "Ending"); 43 } 44 45 GridEditCutpoints::GridEditCutpoints(MythMainWindow *parent, 46 NuppelVideoPlayer *player, const char *name) 47 : MythThemedDialog(parent, "grideditcutpoints", "", name) 48 { 49 m_player = player; 50 m_images = new GridEditImages(this, player); 51 52 int i; 53 for (i = m_gridimages.minIndex(); i < m_gridimages.maxIndex(); i++) 54 { 55 m_gridimages[i] = NULL; 56 } 57 58 usedSubVideoCount=0; 59 60 QSize videoSizeMain, videoSizeSmall; 61 62 m_gridimages[0] = getUIGridEditImageType("mainvideo"); 63 if (m_gridimages[0]) 64 videoSizeMain = m_gridimages[0]->getScreenArea().size(); 65 else 66 VERBOSE(VB_IMPORTANT, "FATAL: Couldn't find mainedit:mainvideo"); 67 68 for (i = 1; i < m_gridimages.maxIndex(); i++) 69 { 70 QString p = QString("videop%1").arg(i); 71 QString m = QString("videom%1").arg(i); 72 73 // Minus frame i 74 m_gridimages[-i] = getUIGridEditImageType(m); 75 if (m_gridimages[-i]) 76 { 77 QSize tmpVideoSizeSmall = m_gridimages[-i]->getScreenArea().size(); 78 if (videoSizeSmall.isValid() && videoSizeSmall != tmpVideoSizeSmall) 79 VERBOSE(VB_IMPORTANT, 80 QString("Multiple sizes found for edit videos (%1)").arg(m)); 81 else 82 videoSizeSmall = tmpVideoSizeSmall; 83 if (i > usedSubVideoCount) usedSubVideoCount=i; 84 } 85 86 m_gridimages[i] = getUIGridEditImageType(p); 87 if (m_gridimages[i]) 88 { 89 QSize tmpVideoSizeSmall = m_gridimages[i]->getScreenArea().size(); 90 if (videoSizeSmall.isValid() && videoSizeSmall != tmpVideoSizeSmall) 91 VERBOSE(VB_IMPORTANT, 92 QString("Multiple sizes found for edit videos (%1)").arg(p)); 93 else 94 videoSizeSmall = tmpVideoSizeSmall; 95 if (i > usedSubVideoCount) usedSubVideoCount=i; 96 } 97 } 98 m_images->SetVideoInfo(usedSubVideoCount, videoSizeMain, videoSizeSmall); 99 100 m_player->SetHalfPageSize(usedSubVideoCount); 101 m_slider = getUIGridEditSliderType("positionbar"); 102 if (!m_slider) 103 VERBOSE(VB_GENERAL, "Missing positionbar for GridEditCutpoints"); 104 105 // Get Status boxes 106 { 107 m_framenum = getUITextType("framenum"); 108 m_time = getUITextType("time"); 109 m_cutind = getUITextType("cutind"); 110 m_jumpstyle = getUITextType("jumpstyle"); 111 m_updatingind = getUITextType("updatingind"); 112 } 113 114 VERBOSE(VB_GENERAL, QString("main = (%1, %2) small = (%3, %4)") 115 .arg(videoSizeMain.width()).arg(videoSizeMain.height()) 116 .arg(videoSizeSmall.width()).arg(videoSizeSmall.height())); 117 118 slowMotionDirection = 1; // start off play forward 119 slowMotionActive = false; 120 readyForNextFrame = false; 121 slowMotionTimer = new QTimer(this); 122 QObject::connect(slowMotionTimer, SIGNAL(timeout()), 123 this, SLOT(updateSlowMotion())); 124 125 movingCutpoint = false; 126 // Create blank pixmaps... 127 128 updateBackground(); 129 130 updateStats(); 131 132 setNoErase(); 133 gContext->addListener(this); 134 135 updateForeground(); 136 } 137 138 GridEditCutpoints::~GridEditCutpoints() 139 { 140 if (m_images) 141 { 142 delete m_images; 143 m_images = NULL; 144 } 145 gContext->removeListener(this); 146 } 147 148 void GridEditCutpoints::displayInitialFrame() 149 { 150 refreshImages(true); 151 refreshCutList(); 152 updateStats(); 153 SetUpdating(false); 154 } 155 156 void GridEditCutpoints::updateSlowMotion() 157 { 158 if (!slowMotionActive) 159 slowMotionTimer->stop(); 160 else if (readyForNextFrame && slowMotionDirection != 0) 161 { 162 readyForNextFrame=false; 163 164 if (slowMotionDirection > 0) 165 EditHandleRight(); 166 else if (slowMotionDirection < 0) 167 EditHandleLeft(); 168 } 169 } 170 171 172 void GridEditCutpoints::setSlowMotionSpeed() 173 { 174 // slowMotionDirection is max FPS 175 176 if (slowMotionDirection != 0) 177 { 178 int smd = slowMotionDirection; 179 if (smd < 0) smd = -smd; 180 int timeout = 1000 / smd; 181 182 slowMotionTimer->start(timeout); 183 } 184 SetUpdating(true, QString("%1 FPS max").arg(slowMotionDirection)); 185 } 186 187 188 void GridEditCutpoints::keyPressEvent(QKeyEvent *e) 189 { 190 // keyDown limits keyrepeats to prevent continued scrolling 191 // after key is released. Note: Qt's keycompress should handle 192 // this but will fail with fast key strokes and keyboard repeat 193 // enabled. Keys will not be marked as autorepeat and flood buffer. 194 // setFocusPolicy(QWidget::ClickFocus) in constructor is important 195 // or keyRelease events will not be received after a refocus. 196 197 bool handled = false; 198 199 QStringList actions; 200 gContext->GetMainWindow()->TranslateKeyPress("TV Editing", e, actions); 201 202 { 203 for (unsigned int i = 0; i < actions.size() && !handled; i++) 204 { 205 QString action = actions[i]; 206 handled = true; 207 208 if (action == "SELECT") 209 { 210 if (slowMotionActive) 211 { 212 slowMotionActive = false; 213 slowMotionTimer->stop(); 214 } 215 else if (movingCutpoint) 216 { 217 // Move cutpoint 218 m_player->DeleteMark(savedCutpoint); 219 m_player->AddMark(m_images->GetCurrentFrameNumber(), savedCutType); 220 movingCutpoint = false; 221 refreshCutList(); 222 refreshImages(); 223 } 224 else 225 handleSelect(); 226 } 227 else if (action == "PAUSE") 228 { 229 if (movingCutpoint) 230 MythPopupBox::showOkPopup(gContext->GetMainWindow(), 231 "Moving Cutpoint", 232 "Slow Motion Unavailable when moving cutpoint"); 233 else if (slowMotionActive) 234 { 235 slowMotionActive = false; 236 slowMotionTimer->stop(); 237 } 238 } 239 else if (action == "SLOWMO") 240 { 241 if (movingCutpoint) 242 MythPopupBox::showOkPopup(gContext->GetMainWindow(), 243 "Moving Cutpoint", 244 "Slow Motion Unavailable when moving cutpoint"); 245 else 246 { 247 if (slowMotionActive) 248 { 249 slowMotionActive = false; 250 slowMotionTimer->stop(); 251 } 252 else 253 { 254 slowMotionActive = true; 255 readyForNextFrame = true; 256 slowMotionDirection = 1; 257 258 // force to either 1 frame. 1/2 page or full page motion 259 int i; 260 // move to 1 frame if on cutpoint 261 for (i = 0; m_player->GetSeekAmountPos() < 2 && i < 10; i++) 262 m_player->UpdateSeekAmount(false); 263 264 // move to fullpage if higher 265 for (i = 0; m_player->GetSeekAmountPos() > 4 && i < 10; i++) 266 m_player->UpdateSeekAmount(true); 267 268 setSlowMotionSpeed(); 269 } 270 } 271 } 272 else if (action == "LEFT") 273 { 274 if (slowMotionActive) 275 { 276 slowMotionDirection--; 277 setSlowMotionSpeed(); 278 } 279 else 280 { 281 SetUpdating(true); 282 283 EditHandleLeft(); 284 refreshImages(false); 285 } 286 } 287 else if (action == "RIGHT" ) 288 { 289 if (slowMotionActive) 290 { 291 slowMotionDirection++; 292 setSlowMotionSpeed(); 293 } 294 else 295 { 296 SetUpdating(true); 297 298 EditHandleRight(); 299 refreshImages(false); 300 } 301 } 302 else if (action == "UP") 303 m_player->UpdateSeekAmount(true); 304 else if (action == "DOWN") 305 { 306 if ((movingCutpoint || slowMotionActive) && m_player->GetSeekAmountPos() == 2) 307 MythPopupBox::showOkPopup(gContext->GetMainWindow(), 308 "Moving Cutpoint", 309 "CutPoint skip Unavailable"); 310 else 311 m_player->UpdateSeekAmount(false); 312 } 313 else if (action == "CLEARMAP") 314 { 315 if (movingCutpoint || slowMotionActive) 316 MythPopupBox::showOkPopup(gContext->GetMainWindow(), 317 "Moving Cutpoint", 318 "Clear Cut Map Unavailable"); 319 else 320 { 321 SetUpdating(true); 322 m_player->EditHandleClearMap(); 323 refreshCutList(); 324 } 325 } 326 else if (action == "INVERTMAP") 327 { 328 if (movingCutpoint || slowMotionActive) 329 MythPopupBox::showOkPopup(gContext->GetMainWindow(), 330 "Moving Cutpoint", 331 "Invert Cut Map Unavailable"); 332 else 333 { 334 SetUpdating(true); 335 m_player->EditHandleInvertMap(); 336 refreshCutList(); 337 } 338 } 339 else if (action == "LOADCOMMSKIP") 340 { 341 if (movingCutpoint || slowMotionActive) 342 MythPopupBox::showOkPopup(gContext->GetMainWindow(), 343 "Moving Cutpoint", 344 "Load Comm Skip Map Unavailable"); 345 else 346 { 347 SetUpdating(true); 348 m_player->EditHandleLoadCommSkip(); 349 refreshCutList(); 350 } 351 } 352 else if (action == "PREVCUT") 353 { 354 if (movingCutpoint || slowMotionActive) 355 MythPopupBox::showOkPopup(gContext->GetMainWindow(), 356 "Moving Cutpoint", 357 "Prev Cut Unavailable"); 358 else 359 { 360 SetUpdating(true); 361 EditHandlePrevCut(); 362 refreshImages(false); 363 } 364 } 365 else if (action == "NEXTCUT") 366 { 367 if (movingCutpoint || slowMotionActive) 368 MythPopupBox::showOkPopup(gContext->GetMainWindow(), 369 "Moving Cutpoint", 370 "Next Cut Unavailable"); 371 else 372 { 373 SetUpdating(true); 374 EditHandleNextCut(); 375 refreshImages(false); 376 } 377 } 378 else if (action == "BIGJUMPREW") 379 { 380 SetUpdating(true); 381 EditHandleBigJumpRew(); 382 refreshImages(false); 383 } 384 else if (action == "BIGJUMPFWD") 385 { 386 SetUpdating(true); 387 EditHandleBigJumpFwd(); 388 refreshImages(false); 389 } 390 else if (action == "ESCAPE" && movingCutpoint) 391 movingCutpoint = false; 392 else if (action == "ESCAPE" || action == "TOGGLEEDIT" || 393 action == "MENU") 394 escape(); 395 else 396 handled = false; 397 398 if (handled) 399 updateStats(); 400 if (movingCutpoint) 401 SetUpdating(true, "Moving Cutpoint"); 402 else if (!slowMotionActive) 403 SetUpdating(false); 404 } 405 } 406 407 if (!handled) 408 MythDialog::keyPressEvent(e); 409 } 410 411 void GridEditCutpoints::EditHandleLeft(int seektype) 412 { 413 long long seekamount = m_player->GetSeekAmount(); 414 bool cutpointseek = false; 415 416 if (seektype == -2 || seekamount == -2) 417 cutpointseek = true; 418 else 419 { 420 // seektype == 1 for normal, 10 for bigjump 421 seekamount *= seektype; 422 } 423 424 if (seekamount < 0) // Invalid -- keyframe 425 seekamount = 1; 426 427 m_images->SeekLeft(seekamount, cutpointseek); 428 429 refreshImages(true); 430 431 } 432 433 void GridEditCutpoints::EditHandleRight(int seektype) 434 { 435 long long seekamount = m_player->GetSeekAmount(); 436 bool cutpointseek=false; 437 438 if (seektype == -2 || seekamount == -2) 439 cutpointseek = true; 440 else 441 { 442 // seektype == 1 for normal, 10 for bigjump 443 seekamount *= seektype; 444 } 445 446 if (seekamount < 0) // Invalid -- keyframe 447 seekamount = 1; 448 449 m_images->SeekRight(seekamount, cutpointseek); 450 451 refreshImages(true); 452 453 } 454 455 void GridEditCutpoints::handleSelect(void) 456 { 457 bool needupdate = false; 458 // add / update cutpoint 459 // -or- 460 // delete / flip / move cutpoint 461 462 // if no cut points on screen 463 // "Delete Before" 464 // "Delete After" 465 466 // if on existing cutpoint 467 // "Delete cutpoint" 468 // "Flip directions" 469 470 // FIXME 471 // if a cutpoint exists on the screen but not on the current frame 472 // "Move to current frame" 473 // "Add new" 474 475 FrameStats fs = m_images->GetMainFrameStats(); 476 if (fs.cutInd >= 2) 477 { 478 QString title = ""; 479 QString message = "Cutpoint exists:"; 480 QStringList buttons; 481 buttons.append("Delete cutpoint?"); 482 buttons.append("Move cutpoint?"); 483 if (fs.cutInd == 2) 484 buttons.append("Flip directions (Cut After)?"); 485 else 486 buttons.append("Flip directions (Cut Before)?"); 487 488 DialogCode dc = MythPopupBox::ShowButtonPopup(gContext->GetMainWindow(), 489 title, message, buttons, kDialogCodeButton0); 490 491 if (dc != kDialogCodeRejected) 492 { 493 needupdate = true; 494 if (dc == kDialogCodeButton0) 495 // Delete cutpoint 496 m_player->DeleteMark(fs.frameNumber); 497 498 else if (dc == kDialogCodeButton1) 499 { 500 // Move cutpoint 501 savedCutpoint = fs.frameNumber; 502 savedCutType = m_player->deleteMap[fs.frameNumber]; 503 movingCutpoint = true; 504 // Ensure we're at least at 1 frame motion 505 int i; 506 for (i = 0; m_player->GetSeekAmountPos() < 2 && i < 10; i++) 507 m_player->UpdateSeekAmount(true); 508 509 } 510 else if (dc == kDialogCodeButton2) 511 // Flip 512 m_player->ReverseMark(fs.frameNumber); 513 } 514 } 515 else 516 { 517 QString title = ""; 518 QString message = "Insert New Cutpoint?"; 519 QStringList buttons; 520 buttons.append("Delete before this frame"); 521 buttons.append("Delete after this frame"); 522 DialogCode dc = MythPopupBox::ShowButtonPopup(gContext->GetMainWindow(), 523 title, message, buttons, kDialogCodeButton0); 524 525 if (dc != kDialogCodeRejected) 526 { 527 needupdate = true; 528 if (dc == kDialogCodeButton0) 529 // Delete left 530 m_player->AddMark(fs.frameNumber, MARK_CUT_END); 531 532 else if (dc == kDialogCodeButton1) 533 // Delete Right 534 m_player->AddMark(fs.frameNumber, MARK_CUT_START); 535 } 536 } 537 538 if (needupdate) 539 { 540 refreshCutList(); 541 refreshImages(); 542 } 543 } 544 545 void GridEditCutpoints::refreshImages(bool mainFrameOnly) 546 { 547 // VERBOSE(VB_GENERAL, "Refreshing"); 548 m_images->refreshImages(m_gridimages, mainFrameOnly); 549 if (mainFrameOnly) 550 { 551 repaint(m_gridimages[0]->getOuterBorder()); 552 updateStats(true); 553 } 554 } 555 556 void GridEditCutpoints::refreshCutList() 557 { 558 m_images->refreshCutList(m_gridimages); 559 refreshSlider(); 560 } 561 562 void GridEditCutpoints::refreshSlider() 563 { 564 if (!m_slider) 565 return; 566 567 m_slider->ClearAll(); 568 569 const int CUT_LEFT = 0; 570 const int CUT_RIGHT = 1; 571 572 long long startpos = 0; 573 long long endpos = 0; 574 575 int lastdirection = CUT_LEFT; 576 577 QMap<long long, int> & deleteMap = m_player->deleteMap; 578 QMap<long long, int>::Iterator i = deleteMap.begin(); 579 for (; i != deleteMap.end(); ++i) 580 { 581 long long frame = i.key(); 582 int direction = *i; 583 584 if (direction == CUT_LEFT) 585 { 586 endpos = frame; 587 m_slider->SetRange(startpos, endpos, m_images->GetMaxFrameNumber()); 588 589 startpos = frame; 590 lastdirection = CUT_LEFT; 591 } 592 else if (direction == CUT_RIGHT) 593 { 594 if (lastdirection == CUT_RIGHT) 595 { 596 // continuing within a cutpoint 597 endpos = frame; 598 m_slider->SetRange(startpos, endpos, m_images->GetMaxFrameNumber()); 599 } 600 601 startpos = frame; 602 lastdirection = CUT_RIGHT; 603 } 604 } 605 606 if (lastdirection == CUT_RIGHT) 607 { 608 // continuing within a cutpoint 609 endpos = m_images->GetMaxFrameNumber(); 610 m_slider->SetRange(startpos, endpos, m_images->GetMaxFrameNumber()); 611 } 612 } 613 614 void GridEditCutpoints::updateStats(bool forcerepaint) 615 { 616 int secs, frames, ss, mm, hh; 617 618 FrameStats fs = m_images->GetMainFrameStats(); 619 620 secs = (int)(fs.frameNumber / m_player->GetFrameRate()); 621 frames = fs.frameNumber - (int)(secs * m_player->GetFrameRate()); 622 623 ss = secs; 624 mm = ss / 60; 625 ss %= 60; 626 hh = mm / 60; 627 mm %= 60; 628 629 char timestr[128]; 630 sprintf(timestr, "%d:%02d:%02d.%02d", hh, mm, ss, frames); 631 632 char framestr[128]; 633 sprintf(framestr, "%lld", fs.frameNumber); 634 635 if (m_time) 636 { 637 m_time->SetText(timestr); 638 if (forcerepaint) 639 repaint(m_time->getScreenArea()); 640 } 641 if (m_framenum) 642 { 643 m_framenum->SetText(framestr); 644 if (forcerepaint) 645 repaint(m_framenum->getScreenArea()); 646 } 647 if (m_cutind) 648 { 649 switch (fs.cutInd) { 650 case 0: m_cutind->SetText(""); break; 651 case 1: m_cutind->SetText("Cut"); break; 652 case 2: m_cutind->SetText("Cut Before"); break; 653 case 3: m_cutind->SetText("Cut After"); break; 654 } 655 if (forcerepaint) 656 repaint(m_cutind->getScreenArea()); 657 } 658 659 // Don't need to force update this 660 if (m_jumpstyle) 661 m_jumpstyle->SetText(m_player->GetSeekAmountText()); 662 663 if (m_slider) 664 m_slider->SetPosition(fs.frameNumber, fs.maxFrameNumber); 665 666 } 667 668 void GridEditCutpoints::escape() 669 { 670 // Make sure we're on the right frame when we go back to 671 // Normal edit mode 672 unsetCursor(); 673 accept(); 674 } 675 676 void GridEditCutpoints::SetUpdating(bool active, QString text) 677 { 678 if (m_updatingind) 679 { 680 //VERBOSE(VB_GENERAL, QString("Updating to %1").arg(active)); 681 if (active) 682 { 683 m_updatingind->show(); 684 m_updatingind->SetText(text); 685 } 686 else 687 m_updatingind->hide(); 688 repaint(m_updatingind->getScreenArea()); 689 } 690 } 691 692 void GridEditCutpoints::displayedFramesAreReady() 693 { 694 if (slowMotionActive) 695 { 696 readyForNextFrame=true; 697 if (!slowMotionTimer->isActive()) 698 slowMotionTimer->start(0); 699 } 700 } 701 -
mythtv/libs/libmythtv/grideditcutpoints.h
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmythtv/grideditcutpoints.h myth.20136.0308b/mythtv/libs/libmythtv/grideditcutpoints.h
1 // -*- Mode: c++ -*- 2 #ifndef GRIDEDITCUTPOINTS_H_ 3 #define GRIDEDITCUTPOINTS_H_ 4 5 #include <qstring.h> 6 7 #include "libmyth/mythwidgets.h" 8 #include "uitypes.h" 9 10 #include "grideditimages.h" 11 12 using namespace std; 13 14 class QTimer; 15 class NuppelVideoPlayer; 16 class GridEditImages; 17 18 class MPUBLIC GridEditCutpoints : public MythThemedDialog 19 { 20 Q_OBJECT 21 22 public: 23 // Use this function to instantiate an GridEditCutpoints instance. 24 static void Run(NuppelVideoPlayer *player); 25 26 void refreshImages(bool mainFrameOnly = false); 27 void displayedFramesAreReady(); 28 29 protected: 30 GridEditCutpoints(MythMainWindow *parent, 31 NuppelVideoPlayer *player, const char *name = "GridEditCutpoints"); 32 ~GridEditCutpoints(); 33 34 void displayInitialFrame(); 35 36 void handleSelect(); 37 38 void updateStats(bool forcerepaint = false); 39 40 protected slots: 41 void escape(); 42 void updateSlowMotion(); 43 44 private: 45 void keyPressEvent(QKeyEvent *e); 46 47 // seektype == -2 - cutpoint seek 48 // seektype == 1 - normal seek 49 // seektype == 10 - large seek 50 void EditHandleLeft(int seektype = 1); 51 void EditHandleRight(int seektype = 1); 52 void EditHandlePrevCut() { EditHandleLeft(-2); }; 53 void EditHandleNextCut() { EditHandleRight(-2); }; 54 void EditHandleBigJumpRew() { EditHandleLeft(10); }; 55 void EditHandleBigJumpFwd() { EditHandleRight(10); }; 56 void setSlowMotionSpeed(); 57 void refreshCutList(); 58 void refreshSlider(); 59 60 void SetUpdating(bool active, QString text = "Updating"); 61 62 // Private Data 63 64 NuppelVideoPlayer *m_player; 65 GridEditImages *m_images; 66 67 int usedSubVideoCount; 68 myArray<UIGridEditImageType*, MAX_SUB_VIDEOS> m_gridimages; 69 70 long long savedCutpoint; 71 int savedCutType; 72 bool movingCutpoint; 73 74 UITextType *m_framenum; 75 UITextType *m_time; 76 UITextType *m_cutind; 77 UITextType *m_jumpstyle; 78 UITextType *m_updatingind; 79 80 UIGridEditSliderType *m_slider; 81 QTimer *slowMotionTimer; 82 int slowMotionDirection; 83 bool slowMotionActive; 84 bool readyForNextFrame; 85 }; 86 87 #endif -
mythtv/libs/libmythtv/grideditimages.cpp
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmythtv/grideditimages.cpp myth.20136.0308b/mythtv/libs/libmythtv/grideditimages.cpp
1 #include <math.h> 2 #include <unistd.h> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 #include <QApplication> 8 #include <QPainter> 9 #include <QFont> 10 #include <QKeyEvent> 11 #include <QEvent> 12 #include <QPixmap> 13 #include <QPaintEvent> 14 #include <QCursor> 15 #include <QImage> 16 #include <QLayout> 17 #include <QLabel> 18 #include <QDateTime> 19 #include <QRect> 20 21 #include "mythcontext.h" 22 #include "mythdbcon.h" 23 #include "grideditimages.h" 24 #include "grideditcutpoints.h" 25 #include "NuppelVideoPlayer.h" 26 27 GridEditImages::GridEditImages(GridEditCutpoints *editor, NuppelVideoPlayer *player) 28 { 29 m_editor = editor; 30 m_player = player; 31 usedSubVideoCount = 0; 32 33 lastmovewasright= true; 34 35 int i; 36 for (i = stillFrames.minIndex(); i <= stillFrames.maxIndex(); i++) 37 { 38 stillFrames[i] = NULL; 39 stillFramesBig[i] = NULL; 40 cutFrames[i] = 0; 41 } 42 43 // Get first frames... 44 stillMainFrameNumber = m_player->GetFramesPlayed(); 45 if (stillMainFrameNumber <= 0) 46 stillMainFrameNumber = 1; 47 48 // maxFrameNumber may be overridden if neccessary 49 maxFrameNumber = m_player->GetTotalFrameCount(); 50 maxFrameNumberNVP = m_player->GetTotalFrameCount(); 51 52 if (stillMainFrameNumber <= 0) 53 stillMainFrameNumber = 1; 54 55 if (stillMainFrameNumber > maxFrameNumber) 56 stillMainFrameNumber = maxFrameNumber; 57 58 getImagesTimer = new QTimer(this); 59 QObject::connect(getImagesTimer, SIGNAL(timeout()), 60 this, SLOT(updateAllFrames())); 61 62 63 } 64 65 GridEditImages::~GridEditImages() 66 { 67 clearStillFrames(); 68 m_player->EditSeekToFrame(stillMainFrameNumber); 69 } 70 71 QPixmap *GridEditImages::makeScaledPixmap(const QImage& qim, QSize sz) 72 { 73 QPixmap *retval; 74 if (qim.size() == sz) 75 { 76 retval = new QPixmap(sz); 77 retval->fromImage(qim); 78 } 79 else 80 { 81 retval = new QPixmap(sz); 82 retval->fill(Qt::black); 83 QPainter p(retval); 84 85 int tl_left = 0; 86 int tl_top = 0; 87 if (sz.width() > qim.width()) 88 tl_left += (sz.width() - qim.width()) / 2; 89 90 if (sz.height() > qim.height()) 91 tl_top += (sz.height() - qim.height()) / 2; 92 93 // VERBOSE(VB_GENERAL, QString("Size mismatch qim(%1, %2) != sz(%3, %4) Shift to (%5, %6)") 94 // .arg(qim.width()).arg(qim.height()) 95 // .arg(sz.width()).arg(sz.height()) 96 // .arg(tl_left).arg(tl_top)); 97 98 p.drawImage(tl_left, tl_top, qim); 99 } 100 return retval; 101 } 102 103 #define FRAME_DEBUG 0 104 105 void GridEditImages::getMainStillFrame() 106 { 107 if (!stillFrames[0]) 108 getSpecificFrame(0); 109 } 110 111 bool GridEditImages::getStillFrames(int limits, int maxcount) 112 { 113 // 114 // returns true if no more frames to get 115 116 // This will fill in all the missing frames in the cache 117 118 int i; 119 bool getFutureFramesFirst = false; 120 121 // Get Boundaries for Minus and Plus arrays 122 // Don't go to absolute end - it'll slow down seeking 123 // when you go 1 frame left and right 124 125 // Note starti is negative 126 // Negative frames are before the main frame 127 // Frame #0 is the main frame 128 // Positive frames are after the main frame 129 int starti = stillFrames.minIndex() + 4; 130 int endi = stillFrames.maxIndex() - 4; 131 if (limits == 0) // Current Display only 132 { 133 starti = -(usedSubVideoCount+1); 134 endi = usedSubVideoCount+1; 135 136 } 137 else if (limits == 1) // PreCache only 138 { 139 starti = -preCacheCountLeft; 140 endi = preCacheCountRight; 141 getFutureFramesFirst = lastmovewasright; 142 } 143 144 // Make sure we don't fall of the front of the file 145 if (stillMainFrameNumber + starti <= 0) 146 starti = -(stillMainFrameNumber-1); 147 148 // ... or the back of the file 149 if (endi > (maxFrameNumber - stillMainFrameNumber)) 150 endi = (maxFrameNumber - stillMainFrameNumber); 151 152 if (getFutureFramesFirst) 153 { 154 // If we're filling out the cache and the last move was to the right 155 // grab future frames first before and past frames 156 for (i = 1; i <= endi; i++) 157 { 158 if (!stillFrames[i]) 159 { 160 getSpecificFrame(i); 161 if (--maxcount == 0) return false; 162 } 163 } 164 } 165 166 // grab all appropriate frames 167 168 for (i = starti; i <= endi; i++) 169 { 170 if (!stillFrames[i]) 171 { 172 getSpecificFrame(i); 173 if (--maxcount == 0) return false; 174 } 175 } 176 177 return true; 178 } 179 180 void GridEditImages::getSpecificFrame(int i) 181 { 182 // i is the index withou the cache of frames 183 if (!stillFrames[i]) 184 { 185 // get this frame 186 long long targetFrame = stillMainFrameNumber + i; 187 188 if (!m_player->EditSeekToFrame(targetFrame)) 189 { 190 VERBOSE(VB_GENERAL, QString("Error seeking to Frame[%1] (frame # %2)") 191 .arg(i).arg(targetFrame)); 192 checkMaxFrameCount(); 193 194 stillFramesBig[i] = new QPixmap(videoSizeMain); 195 stillFramesBig[i]->fill(Qt::gray); 196 197 stillFrames[i] = new QPixmap(videoSizeSmall); 198 stillFrames[i]->fill(Qt::gray); 199 } 200 else 201 { 202 cutFrames[i] = m_player->GetCutStatus(targetFrame); 203 QImage qim = m_player->GetScreenGrabOfCurrentFrame(videoSizeMain); 204 205 stillFramesBig[i] = makeScaledPixmap(qim, videoSizeMain); 206 stillFrames[i] = makeScaledPixmap(qim.scaled(videoSizeSmall, Qt::KeepAspectRatio), 207 videoSizeSmall); 208 209 #if FRAME_DEBUG 210 VERBOSE(VB_GENERAL, QString("stillFrames[%1] = %2 (%3)") 211 .arg(i) 212 .arg(targetFrame) 213 .arg(cutFrames[i])); 214 #endif 215 } 216 } 217 } 218 219 void GridEditImages::SetVideoInfo(int vcount, QSize sizeMain, QSize sizeSmall) 220 { 221 usedSubVideoCount = vcount; 222 preCacheCountLeft = vcount+1; 223 preCacheCountRight = vcount+1; 224 videoSizeMain = sizeMain; 225 videoSizeSmall = sizeSmall; 226 227 // start to grab the current images 228 getMainStillFrame(); 229 getImagesTimer->start(0); 230 } 231 232 void GridEditImages::SetPreCacheLeft(int pccount) 233 { 234 preCacheCountLeft = usedSubVideoCount + pccount; 235 preCacheCountRight = usedSubVideoCount + 1; 236 // pccount is too big, then it's a waste of tim to precache 237 // i.e. 1 second jumps... 238 // We'll end up just throwing the extra frames away 239 if (preCacheCountLeft > stillFrames.maxIndex()) 240 preCacheCountLeft = usedSubVideoCount + 1; 241 } 242 243 void GridEditImages::SetPreCacheRight(int pccount) 244 { 245 preCacheCountLeft = usedSubVideoCount + 1; 246 preCacheCountRight = usedSubVideoCount + pccount; 247 // pccount is too big, then it's a waste of tim to precache 248 // i.e. 1 second jumps... 249 // We'll end up just throwing the extra frames away 250 if (preCacheCountRight > stillFrames.maxIndex()) 251 preCacheCountRight = usedSubVideoCount + 1; 252 } 253 254 void GridEditImages::updateAllFrames() 255 { 256 // getStillFrames() returns 'true' when it's gotten all requested frames 257 258 // First call is to grab frames to be actively displayed 259 if (getStillFrames(0, 1)) 260 { 261 // Tell the editor that all of the currently display frames are ready 262 m_editor->displayedFramesAreReady(); 263 264 if (getStillFrames(1, 1)) // Second, try for pre-cache frames 265 { 266 if (getStillFrames(2, 1)) // Third, get any other frames till we've filled our storage 267 { 268 getImagesTimer->stop(); 269 } 270 } 271 } 272 273 m_editor->refreshImages(); 274 275 } 276 277 void GridEditImages::clearStillFrames() 278 { 279 int i; 280 for (i = stillFrames.minIndex(); i <= stillFrames.maxIndex(); i++) 281 { 282 if (stillFrames[i]) 283 { 284 delete stillFrames[i]; 285 stillFrames[i] = NULL; 286 } 287 if (stillFramesBig[i]) 288 { 289 delete stillFramesBig[i]; 290 stillFramesBig[i] = NULL; 291 } 292 cutFrames[i] = 0; 293 } 294 } 295 296 bool GridEditImages::shiftStillFramesLeft(long long offset) 297 { 298 if (offset > 2 * stillFrames.maxIndex()) 299 { 300 // Dump all cached data and re-get it 301 clearStillFrames(); 302 } 303 else if (offset < 0) 304 { 305 VERBOSE(VB_IMPORTANT, QString("Offset (%1) < 0").arg(offset)); 306 // Dump all cached data and re-get it 307 clearStillFrames(); 308 offset = 0; 309 } 310 else if (offset != 0) 311 { 312 // Shift backwards in the stream by offset 313 314 // All frames will actually shift to the right. 315 // frame 'n' will become frame 'n+1' 316 // frame stillFrameMinus[1] will become mainframe 317 // frame stillFramePlus[max] will drop off 318 319 // shove extra frames into the excess space above usedSubVideos 320 321 if (offset >= stillMainFrameNumber) 322 offset = (stillMainFrameNumber-1); 323 324 // printStillFrameStats("Before SL"); 325 int i,j; 326 int minIndex = stillFrames.minIndex(); 327 int maxIndex = stillFrames.maxIndex(); 328 for (i = 0; i < offset; i++) 329 { 330 331 if (stillFrames[maxIndex]) 332 { 333 delete stillFrames[maxIndex]; 334 delete stillFramesBig[maxIndex]; 335 } 336 337 for (j = maxIndex; j > minIndex; j--) { 338 stillFrames[j] = stillFrames[j-1]; 339 stillFramesBig[j] = stillFramesBig[j-1]; 340 cutFrames[j] = cutFrames[j-1]; 341 } 342 343 stillFrames[minIndex] = NULL; 344 stillFramesBig[minIndex] = NULL; 345 cutFrames[minIndex] = 0; 346 } 347 348 // printStillFrameStats("After SL"); 349 350 } 351 352 stillMainFrameNumber -= offset; 353 if (stillMainFrameNumber < 1) 354 stillMainFrameNumber = 1; 355 356 return (stillFramesBig[0] != NULL); 357 } 358 359 bool GridEditImages::shiftStillFramesRight(long long offset) 360 { 361 //VERBOSE(VB_GENERAL, QString("Offset = %1").arg(offset)); 362 if (offset > 2 * stillFrames.maxIndex()) 363 { 364 // Dump all cached data and re-get it 365 clearStillFrames(); 366 } 367 else if (offset < 0) 368 { 369 VERBOSE(VB_IMPORTANT, QString("Offset (%1) < 0").arg(offset)); 370 // Dump all cached data and re-get it 371 clearStillFrames(); 372 offset = 0; 373 } 374 else if (offset != 0) 375 { 376 377 // Shift forwards in the stream by offset 378 379 // All frames will actually shift to the left. 380 // frame 'n' will become frame 'n-1' 381 // frame stillFramePlus[1] will become mainframe 382 // frame stillFrameMinus[max] will drop off 383 384 // shove extra frames into the excess space above usedSubVideos 385 386 if (stillMainFrameNumber + offset > maxFrameNumber) 387 { 388 offset = (maxFrameNumber - stillMainFrameNumber); 389 VERBOSE(VB_GENERAL, QString("new Offset = %1").arg(offset)); 390 } 391 //printStillFrameStats("Before SR"); 392 393 int i,j; 394 int minIndex = stillFrames.minIndex(); 395 int maxIndex = stillFrames.maxIndex(); 396 397 for (i = 0; i < offset; i++) 398 { 399 if (stillFrames[minIndex]) 400 { 401 delete stillFrames[minIndex]; 402 delete stillFramesBig[minIndex]; 403 } 404 405 for (j = minIndex; j < maxIndex; j++) { 406 stillFrames[j] = stillFrames[j+1]; 407 stillFramesBig[j] = stillFramesBig[j+1]; 408 cutFrames[j] = cutFrames[j+1]; 409 } 410 411 stillFrames[maxIndex] = NULL; 412 stillFramesBig[maxIndex] = NULL; 413 cutFrames[maxIndex] = 0; 414 } 415 416 //printStillFrameStats("After SR"); 417 418 } 419 stillMainFrameNumber += offset; 420 if (stillMainFrameNumber > maxFrameNumber ) 421 stillMainFrameNumber = maxFrameNumber; 422 423 return (stillFramesBig[0] != NULL); 424 } 425 426 void GridEditImages::printStillFrameStats(QString caption) 427 { 428 int i; 429 // Debug info for frame cache 430 QString foundframes= caption + " Found Frames: "; 431 432 for (i = stillFrames.minIndex(); i <= stillFrames.maxIndex(); i++) 433 if (stillFrames[i]) 434 foundframes += QString("%1 ").arg(i); 435 436 VERBOSE(VB_GENERAL, foundframes); 437 } 438 439 void GridEditImages::refreshCutList(myArray<UIGridEditImageType*, MAX_SUB_VIDEOS> &gridimages) 440 { 441 int i; 442 for (i = stillFrames.minIndex(); i <= stillFrames.maxIndex(); i++) 443 { 444 if (stillFrames[i]) 445 { 446 cutFrames[i] = m_player->GetCutStatus(stillMainFrameNumber+i); 447 if (gridimages[i]) 448 gridimages[i]->setCutStatus(cutFrames[i]); 449 } 450 } 451 } 452 453 bool GridEditImages::refreshImages(myArray<UIGridEditImageType*, MAX_SUB_VIDEOS> &gridimages, 454 bool mainFrameOnly) 455 { 456 // VERBOSE(VB_GENERAL, "Start"); 457 bool alldone = true; 458 if (!stillFramesBig[0]) 459 VERBOSE(VB_GENERAL, QString("Null Big Main frame %1").arg(stillMainFrameNumber)); 460 gridimages[0]->setPixmap(stillFramesBig[0], 461 stillMainFrameNumber, 462 cutFrames[0]); 463 464 if (!mainFrameOnly) 465 { 466 int i; 467 for (i = -usedSubVideoCount; i <= usedSubVideoCount; i++) 468 { 469 if (i != 0) // index 0 done above already 470 { 471 if (stillFrames[i] == NULL) 472 alldone = false; 473 gridimages[i]->setPixmap(stillFrames[i], 474 (stillMainFrameNumber + i), 475 cutFrames[i]); 476 } 477 } 478 } 479 480 // VERBOSE(VB_GENERAL, "Finish"); 481 return alldone; 482 } 483 484 485 // Back up x frames 486 void GridEditImages::SeekLeft(long long seekamount, bool cutpointseek) 487 { 488 lastmovewasright = false; 489 getImagesTimer->stop(); 490 491 if (cutpointseek) 492 seekamount = m_player->CalcCutPointSeek(stillMainFrameNumber, false); 493 494 //VERBOSE(VB_GENERAL, QString("SeekLeft %1, cutpoint = %2").arg(seekamount).arg(cutpointseek)); 495 SetPreCacheLeft(seekamount); 496 if (!shiftStillFramesLeft(seekamount)) 497 { 498 //VERBOSE(VB_GENERAL, QString("shiftStillFramesLeft(%1) == false") 499 // .arg(seekamount)); 500 // Need to grab the main frame 501 502 getMainStillFrame(); 503 } 504 505 getImagesTimer->start(0); 506 } 507 508 void GridEditImages::SeekRight(long long seekamount, bool cutpointseek) 509 { 510 lastmovewasright = true; 511 getImagesTimer->stop(); 512 513 if (cutpointseek) 514 seekamount = m_player->CalcCutPointSeek(stillMainFrameNumber, true); 515 516 //VERBOSE(VB_GENERAL, QString("SeekRight %1, cutpoint = %2").arg(seekamount).arg(cutpointseek)); 517 SetPreCacheLeft(seekamount); 518 if (!shiftStillFramesRight(seekamount)) 519 { 520 //VERBOSE(VB_GENERAL, QString("shiftStillFramesLeft(%1) == false") 521 // .arg(seekamount)); 522 // Need to grab the main frame 523 524 getMainStillFrame(); 525 } 526 527 getImagesTimer->start(0); 528 } 529 530 void GridEditImages::checkMaxFrameCount() 531 { 532 long long tfc = m_player->GetTotalFrameCount(); 533 if (tfc != maxFrameNumberNVP) 534 { 535 VERBOSE(VB_GENERAL, QString("Updating: tfc %1, mfn %2, mfnNVP %3") 536 .arg(tfc).arg(maxFrameNumber).arg(maxFrameNumberNVP)); 537 // Check to see if things changed 538 maxFrameNumber = tfc; 539 maxFrameNumberNVP = tfc; 540 } 541 } 542 543 FrameStats GridEditImages::GetMainFrameStats() 544 { 545 FrameStats result; 546 547 result.frameNumber = stillMainFrameNumber; 548 result.cutInd = cutFrames[0]; 549 result.maxFrameNumber = maxFrameNumber; 550 551 return result; 552 } 553 -
mythtv/libs/libmythtv/grideditimages.h
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmythtv/grideditimages.h myth.20136.0308b/mythtv/libs/libmythtv/grideditimages.h
1 // -*- Mode: c++ -*- 2 #ifndef GRIDEDITIMAGES_H_ 3 #define GRIDEDITIMAGES_H_ 4 5 #include <qstring.h> 6 7 #include "libmyth/mythwidgets.h" 8 9 using namespace std; 10 11 class QTimer; 12 class NuppelVideoPlayer; 13 class GridEditCutpoints; 14 15 #define MAX_SUB_VIDEOS 25 16 17 // Simple class to allow array indexing from -MAX_SUB_VIDEOS to +MAX_SUB_VIDEOS 18 template<class T, int COUNT> class myArray 19 { 20 public: 21 myArray() { memset(_array, 0, sizeof(_array));}; 22 23 T& operator[](int i) { return _array[COUNT+i]; }; 24 int minIndex() const { return -COUNT; }; 25 int maxIndex() const { return COUNT; }; 26 27 private: 28 T _array[2*COUNT+1]; 29 }; 30 31 class FrameStats 32 { 33 public: 34 long long frameNumber; 35 int cutInd; 36 long long maxFrameNumber; 37 }; 38 39 class MPUBLIC GridEditImages : public QObject 40 { 41 Q_OBJECT 42 43 public: 44 GridEditImages(GridEditCutpoints *er, NuppelVideoPlayer *player); 45 ~GridEditImages(); 46 47 void refreshCutList(myArray<UIGridEditImageType*, MAX_SUB_VIDEOS> &gridimages); 48 49 // return true if anything changed 50 bool refreshImages(myArray<UIGridEditImageType*, MAX_SUB_VIDEOS> &gridimages, 51 bool mainFrameOnly); 52 53 void SeekLeft(long long seekamount, bool cutpointseek = false); 54 void SeekRight(long long seekamount, bool cutpointseek = false); 55 56 FrameStats GetMainFrameStats(); 57 long long GetCurrentFrameNumber() const { return stillMainFrameNumber; } 58 long long GetMaxFrameNumber() const { return maxFrameNumber; } 59 60 void SetVideoInfo(int vcount, QSize sizeMain, QSize sizeSmall); 61 62 protected slots: 63 void updateAllFrames(); 64 65 private: 66 // Private functions 67 void clearStillFrames(); 68 void printStillFrameStats(QString caption); 69 void checkMaxFrameCount(); 70 71 // 'limits' paramter for getStillFrames(): 72 // 0 = get on screen Frames only 73 // 1 = get preCache Frames only 74 // 2 = get any necessary frames 75 bool getStillFrames(int limits, int maxcount = 1000); 76 void getMainStillFrame(); 77 void getSpecificFrame(int frameindex); 78 79 // return true if anything changed 80 bool shiftStillFramesLeft(long long offset); 81 bool shiftStillFramesRight(long long offset); 82 83 QPixmap *makeScaledPixmap(const QImage& qim, QSize sz); 84 85 void SetPreCacheLeft(int pccount); 86 void SetPreCacheRight(int pccount); 87 88 // Private data 89 // These frames are in the cutlist 90 // 0 == not cut 91 // 1 == cut 92 // 2 == cutpoint (cut left) 93 // 3 == cutpoint (cut right) 94 myArray<int, MAX_SUB_VIDEOS> cutFrames; 95 96 myArray<QPixmap *, MAX_SUB_VIDEOS> stillFrames; 97 myArray<QPixmap *, MAX_SUB_VIDEOS> stillFramesBig; 98 99 QSize videoSizeMain; 100 QSize videoSizeSmall; 101 int usedSubVideoCount; 102 int preCacheCountLeft; 103 int preCacheCountRight; 104 bool lastmovewasright; 105 106 long long stillMainFrameNumber; // frame number for big still picture 107 long long currentFrameNumberNVP; // frame number the NVP should be on 108 long long maxFrameNumber; // max frame number override for NVP 109 long long maxFrameNumberNVP; // Original NVP number 110 111 GridEditCutpoints *m_editor; 112 NuppelVideoPlayer *m_player; 113 114 QTimer *getImagesTimer; 115 116 }; 117 118 #endif -
mythtv/libs/libmythtv/libmythtv.pro
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmythtv/libmythtv.pro myth.20136.0308b/mythtv/libs/libmythtv/libmythtv.pro
363 363 # Misc. frontend 364 364 HEADERS += guidegrid.h infostructs.h 365 365 HEADERS += ttfont.h 366 HEADERS += grideditcutpoints.h grideditimages.h 366 367 SOURCES += guidegrid.cpp infostructs.cpp 367 368 SOURCES += ttfont.cpp 369 SOURCES += grideditcutpoints.cpp grideditimages.cpp 368 370 369 371 using_mheg { 370 372 # DSMCC stuff -
mythtv/libs/libmythtv/tv_play.cpp
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmythtv/tv_play.cpp myth.20136.0308b/mythtv/libs/libmythtv/tv_play.cpp
28 28 #include "remoteencoder.h" 29 29 #include "remoteutil.h" 30 30 #include "guidegrid.h" 31 #include "grideditcutpoints.h" 31 32 //#include "progfind.h" 32 33 #include "NuppelVideoPlayer.h" 33 34 #include "programinfo.h" … … 573 574 REG_KEY("TV Editing", "BIGJUMPFWD", "Jump forward 10x the normal amount", 574 575 ">,."); 575 576 REG_KEY("TV Editing", "TOGGLEEDIT", "Exit out of Edit Mode", "E"); 577 REG_KEY("TV Editing", "SLOWMO", "Slow Motion Play", "Ctrl+P"); 578 REG_KEY("TV Editing", "PAUSE", "Pause", "P"); 576 579 577 580 /* Teletext keys */ 578 581 REG_KEY("Teletext Menu", "NEXTPAGE", "Next Page", "Down"); … … 3232 3235 if (editmode) 3233 3236 { 3234 3237 actx->LockDeleteNVP(__FILE__, __LINE__); 3238 if (actx->nvp && actx->nvp->GetHideEdits()) 3239 { 3240 actx->UnlockDeleteNVP(__FILE__, __LINE__); 3241 return; 3242 } 3235 3243 if (actx->nvp && !actx->nvp->DoKeypress(e)) 3236 3244 editmode = actx->nvp->GetEditMode(); 3237 3245 actx->UnlockDeleteNVP(__FILE__, __LINE__); … … 7699 7707 qApp->postEvent(myWindow, me); 7700 7708 } 7701 7709 7710 void TV::ShowEditRecordingGrid() 7711 { 7712 // post the request to the main UI thread 7713 // it will be caught in eventFilter and processed as CustomEvent 7714 // this will create the program guide window (widget) 7715 // on the main thread and avoid a deadlock on Win32 7716 7717 VERBOSE(VB_GENERAL, "Starting Grid Edit"); 7718 QString message = QString("START_EDIT"); 7719 MythEvent* me = new MythEvent(message); 7720 qApp->postEvent(myWindow, me); 7721 } 7722 7702 7723 void TV::ChangeVolume(PlayerContext *ctx, bool up) 7703 7724 { 7704 7725 ctx->LockDeleteNVP(__FILE__, __LINE__); … … 8346 8367 DoEditSchedule(editType); 8347 8368 } 8348 8369 8370 if (message.left(10) == "START_EDIT") 8371 { 8372 const PlayerContext *mctx = 8373 GetPlayerReadLock(0, __FILE__, __LINE__); 8374 mctx->LockDeleteNVP(__FILE__, __LINE__); 8375 if (mctx->nvp) 8376 mctx->nvp->ShowEditRecordingGrid(); 8377 8378 mctx->UnlockDeleteNVP(__FILE__, __LINE__); 8379 ReturnPlayerLock(mctx); 8380 } 8381 8349 8382 if (message.left(14) == "COMMFLAG_START") 8350 8383 { 8351 8384 QString evchanid = QString::null; -
mythtv/libs/libmythtv/tv_play.h
diff -r -u -N -X diff.exclude.noxml -x myth.20136.0308a -x myth.20136.0308b myth.20136.0308a/mythtv/libs/libmythtv/tv_play.h myth.20136.0308b/mythtv/libs/libmythtv/tv_play.h
199 199 void setInPlayList(bool setting) { inPlaylist = setting; } 200 200 void setUnderNetworkControl(bool setting) { underNetworkControl = setting; } 201 201 202 void ShowEditRecordingGrid(); 202 203 void ShowNoRecorderDialog(const PlayerContext*, 203 204 NoRecorderMsg msgType = kNoRecorders); 204 205 void FinishRecording(int player_idx); ///< Finishes player's recording