2020-09-06 16:47:38 +01:00
/*
2022-12-31 21:19:15 +00:00
* Copyright ( C ) 2020 - 2023 Gavin MacGregor
2020-09-06 16:47:38 +01:00
*
* This file is part of QTeletextMaker .
*
* QTeletextMaker is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* QTeletextMaker is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with QTeletextMaker . If not , see < https : //www.gnu.org/licenses/>.
*/
# include <QApplication>
# include <QDesktopServices>
# include <QFileDialog>
2021-06-03 22:26:54 +01:00
# include <QImage>
2020-09-06 16:47:38 +01:00
# include <QList>
# include <QMenuBar>
# include <QMessageBox>
2021-06-03 22:26:54 +01:00
# include <QPainter>
2021-02-14 17:35:11 +00:00
# include <QPushButton>
2020-09-06 16:47:38 +01:00
# include <QRadioButton>
2021-09-06 22:07:14 +01:00
# include <QRegExp>
2020-11-24 19:01:25 +00:00
# include <QSaveFile>
2020-09-06 16:47:38 +01:00
# include <QScreen>
# include <QSettings>
2021-02-09 15:50:06 +00:00
# include <QShortcut>
2020-09-06 16:47:38 +01:00
# include <QStatusBar>
# include <QToolBar>
2020-12-13 15:46:23 +00:00
# include <QToolButton>
2020-09-06 16:47:38 +01:00
# include <iostream>
# include "mainwindow.h"
2020-11-10 18:48:12 +00:00
# include "levelonecommands.h"
2020-11-24 19:01:25 +00:00
# include "loadsave.h"
2020-09-06 16:47:38 +01:00
# include "mainwidget.h"
2022-05-01 12:55:08 +01:00
# include "pagecomposelinksdockwidget.h"
2020-09-08 12:12:24 +01:00
# include "pageenhancementsdockwidget.h"
2020-09-06 16:47:38 +01:00
# include "pageoptionsdockwidget.h"
# include "palettedockwidget.h"
# include "x26dockwidget.h"
MainWindow : : MainWindow ( )
{
init ( ) ;
setCurrentFile ( QString ( ) ) ;
m_textWidget - > refreshPage ( ) ;
}
MainWindow : : MainWindow ( const QString & fileName )
{
init ( ) ;
loadFile ( fileName ) ;
m_textWidget - > refreshPage ( ) ;
}
void MainWindow : : closeEvent ( QCloseEvent * event )
{
if ( maybeSave ( ) ) {
writeSettings ( ) ;
event - > accept ( ) ;
} else
event - > ignore ( ) ;
}
void MainWindow : : newFile ( )
{
MainWindow * other = new MainWindow ;
other - > tile ( this ) ;
other - > show ( ) ;
}
void MainWindow : : open ( )
{
const QString fileName = QFileDialog : : getOpenFileName ( this ) ;
if ( ! fileName . isEmpty ( ) )
openFile ( fileName ) ;
}
void MainWindow : : openFile ( const QString & fileName )
{
MainWindow * existing = findMainWindow ( fileName ) ;
if ( existing ) {
existing - > show ( ) ;
existing - > raise ( ) ;
existing - > activateWindow ( ) ;
return ;
}
if ( m_isUntitled & & m_textWidget - > document ( ) - > isEmpty ( ) & & ! isWindowModified ( ) ) {
loadFile ( fileName ) ;
m_textWidget - > refreshPage ( ) ;
return ;
}
MainWindow * other = new MainWindow ( fileName ) ;
if ( other - > m_isUntitled ) {
delete other ;
return ;
}
other - > tile ( this ) ;
other - > show ( ) ;
}
2021-08-17 18:40:57 +01:00
static inline bool hasTTISuffix ( const QString & filename )
{
return filename . endsWith ( " .tti " , Qt : : CaseInsensitive ) | | filename . endsWith ( " .ttix " , Qt : : CaseInsensitive ) ;
}
2021-09-05 18:24:51 +01:00
static inline void changeSuffixFromTTI ( QString & filename , const QString & newSuffix )
{
if ( filename . endsWith ( " .tti " , Qt : : CaseInsensitive ) ) {
filename . chop ( 4 ) ;
filename . append ( " . " + newSuffix ) ;
} else if ( filename . endsWith ( " .ttix " , Qt : : CaseInsensitive ) ) {
filename . chop ( 5 ) ;
filename . append ( " . " + newSuffix ) ;
}
}
2020-09-06 16:47:38 +01:00
bool MainWindow : : save ( )
{
2021-08-17 18:40:57 +01:00
// If imported from non-.tti, force "Save As" so we don't clobber the original imported file
return m_isUntitled | | ! hasTTISuffix ( m_curFile ) ? saveAs ( ) : saveFile ( m_curFile ) ;
2020-09-06 16:47:38 +01:00
}
bool MainWindow : : saveAs ( )
{
2021-08-17 18:40:57 +01:00
QString suggestedName = m_curFile ;
// If imported from non-.tti, change extension so we don't clobber the original imported file
if ( suggestedName . endsWith ( " .t42 " , Qt : : CaseInsensitive ) ) {
suggestedName . chop ( 4 ) ;
suggestedName . append ( " .tti " ) ;
}
QString fileName = QFileDialog : : getSaveFileName ( this , tr ( " Save As " ) , suggestedName , " TTI teletext page (*.tti *.ttix) " ) ;
2020-09-06 16:47:38 +01:00
if ( fileName . isEmpty ( ) )
return false ;
return saveFile ( fileName ) ;
}
2022-07-17 15:16:53 +01:00
void MainWindow : : reload ( )
{
if ( m_isUntitled )
return ;
if ( ! m_textWidget - > document ( ) - > undoStack ( ) - > isClean ( ) ) {
const QMessageBox : : StandardButton ret = QMessageBox : : warning ( this , QApplication : : applicationDisplayName ( ) , tr ( " The document \" %1 \" has been modified. \n Do you want to discard your changes? " ) . arg ( QFileInfo ( m_curFile ) . fileName ( ) ) , QMessageBox : : Discard | QMessageBox : : Cancel ) ;
if ( ret ! = QMessageBox : : Discard )
return ;
} else {
const QMessageBox : : StandardButton ret = QMessageBox : : warning ( this , QApplication : : applicationDisplayName ( ) , tr ( " Do you want to reload the document \" %1 \" from disk? " ) . arg ( QFileInfo ( m_curFile ) . fileName ( ) ) , QMessageBox : : Yes | QMessageBox : : No ) ;
if ( ret ! = QMessageBox : : Yes )
return ;
}
int subPageIndex = m_textWidget - > document ( ) - > currentSubPageIndex ( ) ;
m_textWidget - > document ( ) - > clear ( ) ;
loadFile ( m_curFile ) ;
if ( subPageIndex > = m_textWidget - > document ( ) - > numberOfSubPages ( ) )
subPageIndex = m_textWidget - > document ( ) - > numberOfSubPages ( ) - 1 ;
m_textWidget - > document ( ) - > selectSubPageIndex ( subPageIndex , true ) ;
}
2021-06-03 22:26:54 +01:00
void MainWindow : : exportPNG ( )
{
QString exportFileName = QFileDialog : : getSaveFileName ( this , tr ( " Export PNG " ) , QString ( ) , " PNG image (*.png) " ) ;
if ( exportFileName . isEmpty ( ) )
return ;
// Prepare widget image for extraction
m_textWidget - > pauseFlash ( true ) ;
m_textScene - > hideGUIElements ( true ) ;
2022-04-02 22:38:38 +01:00
bool reshowControlCodes = m_textWidget - > showControlCodes ( ) ;
if ( reshowControlCodes )
m_textWidget - > setShowControlCodes ( false ) ;
2021-06-03 22:26:54 +01:00
// Disable exporting in Mix mode as it corrupts the background
bool reMix = m_textWidget - > pageRender ( ) - > mix ( ) ;
2022-04-02 22:38:38 +01:00
if ( reMix ) {
m_textWidget - > setMix ( false ) ;
m_textScene - > setMix ( false ) ;
}
2021-06-03 22:26:54 +01:00
// Extract the image from the scene
QImage interImage = QImage ( m_textScene - > sceneRect ( ) . size ( ) . toSize ( ) , QImage : : Format_RGB32 ) ;
// This ought to make the background transparent in Mix mode, but it doesn't
2022-04-02 22:38:38 +01:00
// if (m_textWidget->pageDecode()->mix())
2021-06-03 22:26:54 +01:00
// interImage.fill(QColor(0, 0, 0, 0));
QPainter interPainter ( & interImage ) ;
m_textScene - > render ( & interPainter ) ;
2021-06-07 21:58:14 +01:00
// Now we've extracted the image we can put the GUI things back
2021-06-03 22:26:54 +01:00
m_textScene - > hideGUIElements ( false ) ;
2022-04-02 22:38:38 +01:00
if ( reshowControlCodes )
m_textWidget - > setShowControlCodes ( true ) ;
if ( reMix ) {
m_textWidget - > setMix ( true ) ;
m_textScene - > setMix ( true ) ;
}
2021-06-03 22:26:54 +01:00
m_textWidget - > pauseFlash ( false ) ;
// Now scale the extracted image to the selected aspect ratio
// We do this in two steps so that anti-aliasing only occurs on vertical lines
// Double the vertical height first
const QImage doubleHeightImage = interImage . scaled ( interImage . width ( ) , interImage . height ( ) * 2 , Qt : : IgnoreAspectRatio , Qt : : FastTransformation ) ;
// If aspect ratio is Pixel 1:2 we're already at the correct scale
if ( m_viewAspectRatio ! = 3 ) {
// Scale it horizontally to the selected aspect ratio
const QImage scaledImage = doubleHeightImage . scaled ( ( int ) ( ( float ) doubleHeightImage . width ( ) * aspectRatioHorizontalScaling [ m_viewAspectRatio ] * 2 ) , doubleHeightImage . height ( ) , Qt : : IgnoreAspectRatio , Qt : : SmoothTransformation ) ;
if ( ! scaledImage . save ( exportFileName , " PNG " ) )
2021-09-10 17:14:27 +01:00
QMessageBox : : warning ( this , QApplication : : applicationDisplayName ( ) , tr ( " Cannot export file %1. " ) . arg ( QDir : : toNativeSeparators ( exportFileName ) ) ) ;
2021-06-03 22:26:54 +01:00
} else if ( ! doubleHeightImage . save ( exportFileName , " PNG " ) )
2021-09-10 17:14:27 +01:00
QMessageBox : : warning ( this , QApplication : : applicationDisplayName ( ) , tr ( " Cannot export file %1. " ) . arg ( QDir : : toNativeSeparators ( exportFileName ) ) ) ;
2021-06-03 22:26:54 +01:00
}
2020-11-29 11:48:08 +00:00
void MainWindow : : exportZXNet ( )
2020-09-06 16:47:38 +01:00
{
2020-11-29 11:48:08 +00:00
QDesktopServices : : openUrl ( QUrl ( " http://zxnet.co.uk/teletext/editor/ " + exportHashStringPage ( m_textWidget - > document ( ) - > currentSubPage ( ) ) + exportHashStringPackets ( m_textWidget - > document ( ) - > currentSubPage ( ) ) ) ) ;
}
void MainWindow : : exportEditTF ( )
{
QDesktopServices : : openUrl ( QUrl ( " http://edit.tf/ " + exportHashStringPage ( m_textWidget - > document ( ) - > currentSubPage ( ) ) ) ) ;
2020-09-06 16:47:38 +01:00
}
void MainWindow : : about ( )
{
2021-05-23 17:25:00 +01:00
QMessageBox : : about ( this , tr ( " About " ) , QString ( " <b>%1</b><br> "
2020-11-10 15:05:24 +00:00
" An open source Level 2.5 teletext page editor.<br> "
2021-05-23 17:25:00 +01:00
" <i>Version %2</i><br><br> "
2022-12-31 21:19:15 +00:00
" Copyright (C) 2020-2023 Gavin MacGregor<br><br> "
2020-11-10 15:05:24 +00:00
" Released under the GNU General Public License version 3<br> "
2021-05-23 17:25:00 +01:00
" <a href= \" https://github.com/gkthemac/qteletextmaker \" >https://github.com/gkthemac/qteletextmaker</a> " ) . arg ( QApplication : : applicationDisplayName ( ) ) . arg ( QApplication : : applicationVersion ( ) ) ) ;
2020-09-06 16:47:38 +01:00
}
void MainWindow : : init ( )
{
setAttribute ( Qt : : WA_DeleteOnClose ) ;
m_isUntitled = true ;
m_textWidget = new TeletextWidget ;
2020-09-08 12:12:24 +01:00
m_pageOptionsDockWidget = new PageOptionsDockWidget ( m_textWidget ) ;
addDockWidget ( Qt : : RightDockWidgetArea , m_pageOptionsDockWidget ) ;
m_pageEnhancementsDockWidget = new PageEnhancementsDockWidget ( m_textWidget ) ;
addDockWidget ( Qt : : RightDockWidgetArea , m_pageEnhancementsDockWidget ) ;
m_x26DockWidget = new X26DockWidget ( m_textWidget ) ;
addDockWidget ( Qt : : RightDockWidgetArea , m_x26DockWidget ) ;
m_paletteDockWidget = new PaletteDockWidget ( m_textWidget ) ;
addDockWidget ( Qt : : RightDockWidgetArea , m_paletteDockWidget ) ;
2022-05-01 12:55:08 +01:00
m_pageComposeLinksDockWidget = new PageComposeLinksDockWidget ( m_textWidget ) ;
addDockWidget ( Qt : : RightDockWidgetArea , m_pageComposeLinksDockWidget ) ;
2020-09-06 16:47:38 +01:00
2021-04-18 16:57:45 +01:00
m_textScene = new LevelOneScene ( m_textWidget , this ) ;
2020-09-06 16:47:38 +01:00
createActions ( ) ;
createStatusBar ( ) ;
readSettings ( ) ;
m_textView = new QGraphicsView ( this ) ;
m_textView - > setScene ( m_textScene ) ;
2021-06-07 21:58:14 +01:00
if ( m_viewSmoothTransform )
m_textView - > setRenderHints ( QPainter : : SmoothPixmapTransform ) ;
2020-09-06 16:47:38 +01:00
m_textView - > setBackgroundBrush ( QBrush ( QColor ( 32 , 48 , 96 ) ) ) ;
setSceneDimensions ( ) ;
setCentralWidget ( m_textView ) ;
connect ( m_textWidget - > document ( ) , & TeletextDocument : : cursorMoved , this , & MainWindow : : updateCursorPosition ) ;
2021-04-26 22:08:28 +01:00
connect ( m_textWidget - > document ( ) , & TeletextDocument : : selectionMoved , m_textScene , & LevelOneScene : : updateSelection ) ;
2020-09-06 16:47:38 +01:00
connect ( m_textWidget - > document ( ) - > undoStack ( ) , & QUndoStack : : cleanChanged , this , [ = ] ( ) { setWindowModified ( ! m_textWidget - > document ( ) - > undoStack ( ) - > isClean ( ) ) ; } ) ;
2020-09-08 12:12:24 +01:00
connect ( m_textWidget - > document ( ) , & TeletextDocument : : aboutToChangeSubPage , m_x26DockWidget , & X26DockWidget : : unloadX26List ) ;
2020-09-06 16:47:38 +01:00
connect ( m_textWidget - > document ( ) , & TeletextDocument : : subPageSelected , this , & MainWindow : : updatePageWidgets ) ;
connect ( m_textWidget , & TeletextWidget : : sizeChanged , this , & MainWindow : : setSceneDimensions ) ;
2022-04-02 22:38:38 +01:00
connect ( m_textWidget - > pageDecode ( ) , & TeletextPageDecode : : fullScreenColourChanged , m_textScene , & LevelOneScene : : setFullScreenColour ) ;
connect ( m_textWidget - > pageDecode ( ) , & TeletextPageDecode : : fullRowColourChanged , m_textScene , & LevelOneScene : : setFullRowColour ) ;
2021-04-11 13:03:07 +01:00
connect ( m_textWidget , & TeletextWidget : : insertKeyPressed , this , & MainWindow : : toggleInsertMode ) ;
2020-09-06 16:47:38 +01:00
2021-05-04 21:52:51 +01:00
connect ( m_textScene , & LevelOneScene : : mouseZoomIn , this , & MainWindow : : zoomIn ) ;
connect ( m_textScene , & LevelOneScene : : mouseZoomOut , this , & MainWindow : : zoomOut ) ;
2021-02-09 15:50:06 +00:00
QShortcut * blockShortCut = new QShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : Key_J ) , m_textView ) ;
connect ( blockShortCut , & QShortcut : : activated , [ = ] ( ) { m_textWidget - > setCharacter ( 0x7f ) ; } ) ;
2020-09-06 16:47:38 +01:00
setUnifiedTitleAndToolBarOnMac ( true ) ;
updatePageWidgets ( ) ;
2021-05-09 18:55:20 +01:00
m_textView - > setFocus ( ) ;
2020-09-06 16:47:38 +01:00
}
void MainWindow : : tile ( const QMainWindow * previous )
{
//TODO sort out default tiling or positioning
if ( ! previous )
return ;
int topFrameWidth = previous - > geometry ( ) . top ( ) - previous - > pos ( ) . y ( ) ;
if ( ! topFrameWidth )
topFrameWidth = 40 ;
const QPoint pos = previous - > pos ( ) + 2 * QPoint ( topFrameWidth , topFrameWidth ) ;
if ( QGuiApplication : : primaryScreen ( ) - > availableGeometry ( ) . contains ( rect ( ) . bottomRight ( ) + pos ) )
move ( pos ) ;
}
void MainWindow : : createActions ( )
{
QMenu * fileMenu = menuBar ( ) - > addMenu ( tr ( " &File " ) ) ;
QToolBar * fileToolBar = addToolBar ( tr ( " File " ) ) ;
fileToolBar - > setObjectName ( " fileToolBar " ) ;
const QIcon newIcon = QIcon : : fromTheme ( " document-new " , QIcon ( " :/images/new.png " ) ) ;
QAction * newAct = new QAction ( newIcon , tr ( " &New " ) , this ) ;
newAct - > setShortcuts ( QKeySequence : : New ) ;
newAct - > setStatusTip ( tr ( " Create a new file " ) ) ;
connect ( newAct , & QAction : : triggered , this , & MainWindow : : newFile ) ;
fileMenu - > addAction ( newAct ) ;
fileToolBar - > addAction ( newAct ) ;
const QIcon openIcon = QIcon : : fromTheme ( " document-open " , QIcon ( " :/images/open.png " ) ) ;
QAction * openAct = new QAction ( openIcon , tr ( " &Open... " ) , this ) ;
openAct - > setShortcuts ( QKeySequence : : Open ) ;
openAct - > setStatusTip ( tr ( " Open an existing file " ) ) ;
connect ( openAct , & QAction : : triggered , this , & MainWindow : : open ) ;
fileMenu - > addAction ( openAct ) ;
fileToolBar - > addAction ( openAct ) ;
const QIcon saveIcon = QIcon : : fromTheme ( " document-save " , QIcon ( " :/images/save.png " ) ) ;
QAction * saveAct = new QAction ( saveIcon , tr ( " &Save " ) , this ) ;
saveAct - > setShortcuts ( QKeySequence : : Save ) ;
saveAct - > setStatusTip ( tr ( " Save the document to disk " ) ) ;
connect ( saveAct , & QAction : : triggered , this , & MainWindow : : save ) ;
fileMenu - > addAction ( saveAct ) ;
fileToolBar - > addAction ( saveAct ) ;
const QIcon saveAsIcon = QIcon : : fromTheme ( " document-save-as " ) ;
QAction * saveAsAct = fileMenu - > addAction ( saveAsIcon , tr ( " Save &As... " ) , this , & MainWindow : : saveAs ) ;
saveAsAct - > setShortcuts ( QKeySequence : : SaveAs ) ;
saveAsAct - > setStatusTip ( tr ( " Save the document under a new name " ) ) ;
2022-07-17 15:16:53 +01:00
const QIcon reloadIcon = QIcon : : fromTheme ( " document-revert " ) ;
QAction * reloadAct = fileMenu - > addAction ( reloadIcon , tr ( " Reload " ) , this , & MainWindow : : reload ) ;
reloadAct - > setShortcuts ( QKeySequence : : Refresh ) ;
reloadAct - > setStatusTip ( tr ( " Reload the document from disk " ) ) ;
2020-09-06 16:47:38 +01:00
fileMenu - > addSeparator ( ) ;
QMenu * recentMenu = fileMenu - > addMenu ( tr ( " Recent " ) ) ;
connect ( recentMenu , & QMenu : : aboutToShow , this , & MainWindow : : updateRecentFileActions ) ;
m_recentFileSubMenuAct = recentMenu - > menuAction ( ) ;
for ( int i = 0 ; i < m_MaxRecentFiles ; + + i ) {
m_recentFileActs [ i ] = recentMenu - > addAction ( QString ( ) , this , & MainWindow : : openRecentFile ) ;
m_recentFileActs [ i ] - > setVisible ( false ) ;
}
m_recentFileSeparator = fileMenu - > addSeparator ( ) ;
setRecentFilesVisible ( MainWindow : : hasRecentFiles ( ) ) ;
2021-09-05 18:24:51 +01:00
QAction * exportT42Act = fileMenu - > addAction ( tr ( " Export subpage as t42... " ) ) ;
exportT42Act - > setStatusTip ( " Export this subpage as a t42 file " ) ;
connect ( exportT42Act , & QAction : : triggered , this , & MainWindow : : exportT42 ) ;
2021-06-03 22:26:54 +01:00
2021-05-27 21:57:02 +01:00
QMenu * exportHashStringSubMenu = fileMenu - > addMenu ( tr ( " Export subpage to online editor " ) ) ;
2020-11-29 11:48:08 +00:00
QAction * exportZXNetAct = exportHashStringSubMenu - > addAction ( tr ( " Open in zxnet.co.uk " ) ) ;
2021-05-27 21:57:02 +01:00
exportZXNetAct - > setStatusTip ( " Export and open this subpage in the zxnet.co.uk online editor " ) ;
2020-11-29 11:48:08 +00:00
connect ( exportZXNetAct , & QAction : : triggered , this , & MainWindow : : exportZXNet ) ;
QAction * exportEditTFAct = exportHashStringSubMenu - > addAction ( tr ( " Open in edit.tf " ) ) ;
2021-05-27 21:57:02 +01:00
exportEditTFAct - > setStatusTip ( " Export and open this subpage in the edit.tf online editor " ) ;
2020-11-29 11:48:08 +00:00
connect ( exportEditTFAct , & QAction : : triggered , this , & MainWindow : : exportEditTF ) ;
2021-09-05 18:24:51 +01:00
QAction * exportPNGAct = fileMenu - > addAction ( tr ( " Export subpage as PNG... " ) ) ;
exportPNGAct - > setStatusTip ( " Export a PNG image of this subpage " ) ;
connect ( exportPNGAct , & QAction : : triggered , this , & MainWindow : : exportPNG ) ;
2021-09-06 22:07:14 +01:00
QAction * exportM29Act = fileMenu - > addAction ( tr ( " Export subpage X/28 as M/29... " ) ) ;
exportM29Act - > setStatusTip ( " Export this subpage's X/28 packets as a tti file with M/29 packets " ) ;
connect ( exportM29Act , & QAction : : triggered , this , & MainWindow : : exportM29 ) ;
2020-11-29 11:48:08 +00:00
fileMenu - > addSeparator ( ) ;
2020-09-06 16:47:38 +01:00
QAction * closeAct = fileMenu - > addAction ( tr ( " &Close " ) , this , & QWidget : : close ) ;
closeAct - > setShortcut ( tr ( " Ctrl+W " ) ) ;
closeAct - > setStatusTip ( tr ( " Close this window " ) ) ;
const QIcon exitIcon = QIcon : : fromTheme ( " application-exit " ) ;
QAction * exitAct = fileMenu - > addAction ( exitIcon , tr ( " E&xit " ) , qApp , & QApplication : : closeAllWindows ) ;
exitAct - > setShortcuts ( QKeySequence : : Quit ) ;
exitAct - > setStatusTip ( tr ( " Exit the application " ) ) ;
QMenu * editMenu = menuBar ( ) - > addMenu ( tr ( " &Edit " ) ) ;
QToolBar * editToolBar = addToolBar ( tr ( " Edit " ) ) ;
editToolBar - > setObjectName ( " editToolBar " ) ;
2020-11-10 14:39:36 +00:00
const QIcon undoIcon = QIcon : : fromTheme ( " edit-undo " , QIcon ( " :/images/undo.png " ) ) ;
2020-09-06 16:47:38 +01:00
QAction * undoAction = m_textWidget - > document ( ) - > undoStack ( ) - > createUndoAction ( this , tr ( " &Undo " ) ) ;
2020-11-10 14:39:36 +00:00
undoAction - > setIcon ( undoIcon ) ;
2020-09-06 16:47:38 +01:00
editMenu - > addAction ( undoAction ) ;
2020-11-10 14:39:36 +00:00
editToolBar - > addAction ( undoAction ) ;
2020-09-06 16:47:38 +01:00
undoAction - > setShortcuts ( QKeySequence : : Undo ) ;
2020-11-10 14:39:36 +00:00
const QIcon redoIcon = QIcon : : fromTheme ( " edit-redo " , QIcon ( " :/images/redo.png " ) ) ;
2020-09-06 16:47:38 +01:00
QAction * redoAction = m_textWidget - > document ( ) - > undoStack ( ) - > createRedoAction ( this , tr ( " &Redo " ) ) ;
2020-11-10 14:39:36 +00:00
redoAction - > setIcon ( redoIcon ) ;
2020-09-06 16:47:38 +01:00
editMenu - > addAction ( redoAction ) ;
2020-11-10 14:39:36 +00:00
editToolBar - > addAction ( redoAction ) ;
2020-09-06 16:47:38 +01:00
redoAction - > setShortcuts ( QKeySequence : : Redo ) ;
editMenu - > addSeparator ( ) ;
2021-05-03 22:17:51 +01:00
2020-09-06 16:47:38 +01:00
# ifndef QT_NO_CLIPBOARD
2021-05-03 22:17:51 +01:00
const QIcon cutIcon = QIcon : : fromTheme ( " edit-cut " , QIcon ( " :/images/cut.png " ) ) ;
2020-09-06 16:47:38 +01:00
QAction * cutAct = new QAction ( cutIcon , tr ( " Cu&t " ) , this ) ;
cutAct - > setShortcuts ( QKeySequence : : Cut ) ;
2021-05-03 22:17:51 +01:00
cutAct - > setStatusTip ( tr ( " Cut the current selection's contents to the clipboard " ) ) ;
connect ( cutAct , & QAction : : triggered , m_textWidget , & TeletextWidget : : cut ) ;
2020-09-06 16:47:38 +01:00
editMenu - > addAction ( cutAct ) ;
editToolBar - > addAction ( cutAct ) ;
const QIcon copyIcon = QIcon : : fromTheme ( " edit-copy " , QIcon ( " :/images/copy.png " ) ) ;
QAction * copyAct = new QAction ( copyIcon , tr ( " &Copy " ) , this ) ;
copyAct - > setShortcuts ( QKeySequence : : Copy ) ;
2021-05-03 22:17:51 +01:00
copyAct - > setStatusTip ( tr ( " Copy the current selection's contents to the clipboard " ) ) ;
connect ( copyAct , & QAction : : triggered , m_textWidget , & TeletextWidget : : copy ) ;
2020-09-06 16:47:38 +01:00
editMenu - > addAction ( copyAct ) ;
editToolBar - > addAction ( copyAct ) ;
const QIcon pasteIcon = QIcon : : fromTheme ( " edit-paste " , QIcon ( " :/images/paste.png " ) ) ;
QAction * pasteAct = new QAction ( pasteIcon , tr ( " &Paste " ) , this ) ;
pasteAct - > setShortcuts ( QKeySequence : : Paste ) ;
2021-05-03 22:17:51 +01:00
pasteAct - > setStatusTip ( tr ( " Paste the clipboard's contents into the current selection " ) ) ;
connect ( pasteAct , & QAction : : triggered , m_textWidget , & TeletextWidget : : paste ) ;
2020-09-06 16:47:38 +01:00
editMenu - > addAction ( pasteAct ) ;
editToolBar - > addAction ( pasteAct ) ;
editMenu - > addSeparator ( ) ;
# endif // !QT_NO_CLIPBOARD
2020-10-27 15:17:54 +00:00
QAction * insertBlankRowAct = editMenu - > addAction ( tr ( " Insert blank row " ) ) ;
2021-04-04 13:19:54 +01:00
insertBlankRowAct - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : Key_I ) ) ;
2020-10-27 15:17:54 +00:00
insertBlankRowAct - > setStatusTip ( tr ( " Insert a blank row at the cursor position " ) ) ;
connect ( insertBlankRowAct , & QAction : : triggered , [ = ] ( ) { insertRow ( false ) ; } ) ;
QAction * insertCopyRowAct = editMenu - > addAction ( tr ( " Insert copy row " ) ) ;
2021-04-04 13:19:54 +01:00
insertCopyRowAct - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : SHIFT + Qt : : Key_I ) ) ;
2020-10-27 15:17:54 +00:00
insertCopyRowAct - > setStatusTip ( tr ( " Insert a row that's a copy of the row at the cursor position " ) ) ;
connect ( insertCopyRowAct , & QAction : : triggered , [ = ] ( ) { insertRow ( true ) ; } ) ;
QAction * deleteRowAct = editMenu - > addAction ( tr ( " Delete row " ) ) ;
2021-04-04 13:19:54 +01:00
deleteRowAct - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : Key_D ) ) ;
2020-10-27 15:17:54 +00:00
deleteRowAct - > setStatusTip ( tr ( " Delete the row at the cursor position " ) ) ;
connect ( deleteRowAct , & QAction : : triggered , this , & MainWindow : : deleteRow ) ;
editMenu - > addSeparator ( ) ;
2020-09-06 16:47:38 +01:00
QAction * insertBeforeAct = editMenu - > addAction ( tr ( " &Insert subpage before " ) ) ;
insertBeforeAct - > setStatusTip ( tr ( " Insert a blank subpage before this subpage " ) ) ;
connect ( insertBeforeAct , & QAction : : triggered , [ = ] ( ) { insertSubPage ( false , false ) ; } ) ;
QAction * insertAfterAct = editMenu - > addAction ( tr ( " Insert subpage after " ) ) ;
insertAfterAct - > setStatusTip ( tr ( " Insert a blank subpage after this subpage " ) ) ;
connect ( insertAfterAct , & QAction : : triggered , [ = ] ( ) { insertSubPage ( true , false ) ; } ) ;
QAction * insertCopyAct = editMenu - > addAction ( tr ( " Insert subpage copy " ) ) ;
insertCopyAct - > setStatusTip ( tr ( " Insert a subpage that's a copy of this subpage " ) ) ;
connect ( insertCopyAct , & QAction : : triggered , [ = ] ( ) { insertSubPage ( false , true ) ; } ) ;
2020-12-15 21:57:42 +00:00
m_deleteSubPageAction = editMenu - > addAction ( tr ( " Delete subpage " ) ) ;
m_deleteSubPageAction - > setStatusTip ( tr ( " Delete this subpage " ) ) ;
connect ( m_deleteSubPageAction , & QAction : : triggered , this , & MainWindow : : deleteSubPage ) ;
2020-09-06 16:47:38 +01:00
QMenu * viewMenu = menuBar ( ) - > addMenu ( tr ( " &View " ) ) ;
QAction * revealAct = viewMenu - > addAction ( tr ( " &Reveal " ) ) ;
revealAct - > setCheckable ( true ) ;
2021-04-04 13:19:54 +01:00
revealAct - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : Key_R ) ) ;
2020-09-06 16:47:38 +01:00
revealAct - > setStatusTip ( tr ( " Toggle reveal " ) ) ;
2022-04-02 22:38:38 +01:00
connect ( revealAct , & QAction : : toggled , m_textWidget , & TeletextWidget : : setReveal ) ;
2020-09-06 16:47:38 +01:00
QAction * mixAct = viewMenu - > addAction ( tr ( " &Mix " ) ) ;
mixAct - > setCheckable ( true ) ;
2021-04-04 13:19:54 +01:00
mixAct - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : Key_M ) ) ;
2020-09-06 16:47:38 +01:00
mixAct - > setStatusTip ( tr ( " Toggle mix " ) ) ;
2022-04-02 22:38:38 +01:00
connect ( mixAct , & QAction : : toggled , m_textWidget , & TeletextWidget : : setMix ) ;
connect ( mixAct , & QAction : : toggled , m_textScene , & LevelOneScene : : setMix ) ;
2020-09-06 16:47:38 +01:00
QAction * gridAct = viewMenu - > addAction ( tr ( " &Grid " ) ) ;
gridAct - > setCheckable ( true ) ;
2021-04-04 13:19:54 +01:00
gridAct - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : Key_G ) ) ;
2020-09-06 16:47:38 +01:00
gridAct - > setStatusTip ( tr ( " Toggle the text grid " ) ) ;
2021-04-18 16:57:45 +01:00
connect ( gridAct , & QAction : : toggled , m_textScene , & LevelOneScene : : toggleGrid ) ;
2020-09-06 16:47:38 +01:00
2022-04-02 22:38:38 +01:00
QAction * showControlCodesAct = viewMenu - > addAction ( tr ( " Show control codes " ) ) ;
showControlCodesAct - > setCheckable ( true ) ;
showControlCodesAct - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : Key_T ) ) ;
showControlCodesAct - > setStatusTip ( tr ( " Toggle showing of control codes " ) ) ;
connect ( showControlCodesAct , & QAction : : toggled , m_textWidget , & TeletextWidget : : setShowControlCodes ) ;
2020-09-06 16:47:38 +01:00
viewMenu - > addSeparator ( ) ;
QMenu * borderSubMenu = viewMenu - > addMenu ( tr ( " Border " ) ) ;
m_borderActs [ 0 ] = borderSubMenu - > addAction ( tr ( " None " ) ) ;
m_borderActs [ 0 ] - > setStatusTip ( tr ( " View with no border " ) ) ;
m_borderActs [ 1 ] = borderSubMenu - > addAction ( tr ( " Minimal " ) ) ;
m_borderActs [ 1 ] - > setStatusTip ( tr ( " View with minimal border " ) ) ;
2020-11-24 13:16:20 +00:00
m_borderActs [ 2 ] = borderSubMenu - > addAction ( tr ( " Full TV " ) ) ;
m_borderActs [ 2 ] - > setStatusTip ( tr ( " View with full TV overscan border " ) ) ;
2020-09-06 16:47:38 +01:00
QMenu * aspectRatioSubMenu = viewMenu - > addMenu ( tr ( " Aspect ratio " ) ) ;
m_aspectRatioActs [ 0 ] = aspectRatioSubMenu - > addAction ( tr ( " 4:3 " ) ) ;
m_aspectRatioActs [ 0 ] - > setStatusTip ( tr ( " View in 4:3 aspect ratio " ) ) ;
m_aspectRatioActs [ 1 ] = aspectRatioSubMenu - > addAction ( tr ( " 16:9 pillarbox " ) ) ;
m_aspectRatioActs [ 1 ] - > setStatusTip ( tr ( " View in 16:9 with space on either side " ) ) ;
m_aspectRatioActs [ 2 ] = aspectRatioSubMenu - > addAction ( tr ( " 16:9 stretch " ) ) ;
m_aspectRatioActs [ 2 ] - > setStatusTip ( tr ( " View in 16:9 with horizontally stretched text " ) ) ;
m_aspectRatioActs [ 3 ] = aspectRatioSubMenu - > addAction ( tr ( " Pixel 1:2 " ) ) ;
m_aspectRatioActs [ 3 ] - > setStatusTip ( tr ( " View with 1:2 pixel mapping " ) ) ;
QActionGroup * borderGroup = new QActionGroup ( this ) ;
QActionGroup * aspectRatioGroup = new QActionGroup ( this ) ;
for ( int i = 0 ; i < = 3 ; i + + ) {
m_aspectRatioActs [ i ] - > setCheckable ( true ) ;
connect ( m_aspectRatioActs [ i ] , & QAction : : triggered , [ = ] ( ) { setAspectRatio ( i ) ; } ) ;
aspectRatioGroup - > addAction ( m_aspectRatioActs [ i ] ) ;
if ( i = = 3 )
break ;
m_borderActs [ i ] - > setCheckable ( true ) ;
connect ( m_borderActs [ i ] , & QAction : : triggered , [ = ] ( ) { setBorder ( i ) ; } ) ;
borderGroup - > addAction ( m_borderActs [ i ] ) ;
}
2021-06-07 21:58:14 +01:00
viewMenu - > addSeparator ( ) ;
m_smoothTransformAction = viewMenu - > addAction ( tr ( " Smooth font scaling " ) ) ;
m_smoothTransformAction - > setCheckable ( true ) ;
m_smoothTransformAction - > setStatusTip ( tr ( " Toggle smooth font scaling " ) ) ;
connect ( m_smoothTransformAction , & QAction : : toggled , this , & MainWindow : : setSmoothTransform ) ;
2020-09-06 16:47:38 +01:00
QAction * zoomInAct = viewMenu - > addAction ( tr ( " Zoom In " ) ) ;
zoomInAct - > setShortcuts ( QKeySequence : : ZoomIn ) ;
zoomInAct - > setStatusTip ( tr ( " Zoom in " ) ) ;
connect ( zoomInAct , & QAction : : triggered , this , & MainWindow : : zoomIn ) ;
QAction * zoomOutAct = viewMenu - > addAction ( tr ( " Zoom Out " ) ) ;
zoomOutAct - > setShortcuts ( QKeySequence : : ZoomOut ) ;
zoomOutAct - > setStatusTip ( tr ( " Zoom out " ) ) ;
connect ( zoomOutAct , & QAction : : triggered , this , & MainWindow : : zoomOut ) ;
QAction * zoomResetAct = viewMenu - > addAction ( tr ( " Reset zoom " ) ) ;
2021-04-04 13:19:54 +01:00
zoomResetAct - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : Key_0 ) ) ;
2020-09-06 16:47:38 +01:00
zoomResetAct - > setStatusTip ( tr ( " Reset zoom level " ) ) ;
connect ( zoomResetAct , & QAction : : triggered , this , & MainWindow : : zoomReset ) ;
QMenu * insertMenu = menuBar ( ) - > addMenu ( tr ( " &Insert " ) ) ;
QMenu * alphaColourSubMenu = insertMenu - > addMenu ( tr ( " Alphanumeric colour " ) ) ;
QMenu * mosaicColourSubMenu = insertMenu - > addMenu ( tr ( " Mosaic colour " ) ) ;
for ( int i = 0 ; i < = 7 ; i + + ) {
const char * colours [ ] = { " Black " , " Red " , " Green " , " Yellow " , " Blue " , " Magenta " , " Cyan " , " White " } ;
QAction * alphaColour = alphaColourSubMenu - > addAction ( tr ( colours [ i ] ) ) ;
2021-01-26 19:25:57 +00:00
alphaColour - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : Key_0 + i ) ) ;
2020-09-06 16:47:38 +01:00
alphaColour - > setStatusTip ( QString ( " Insert alphanumeric %1 attribute " ) . arg ( QString ( colours [ i ] ) . toLower ( ) ) ) ;
connect ( alphaColour , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( i ) ; } ) ;
QAction * mosaicColour = mosaicColourSubMenu - > addAction ( tr ( colours [ i ] ) ) ;
2021-01-26 19:25:57 +00:00
mosaicColour - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : SHIFT + Qt : : Key_0 + i ) ) ;
2020-09-06 16:47:38 +01:00
mosaicColour - > setStatusTip ( QString ( " Insert mosaic %1 attribute " ) . arg ( QString ( colours [ i ] ) . toLower ( ) ) ) ;
connect ( mosaicColour , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( i + 0x10 ) ; } ) ;
}
QMenu * mosaicsStyleSubMenu = insertMenu - > addMenu ( tr ( " Mosaics style " ) ) ;
QAction * mosaicsSeparatedAct = mosaicsStyleSubMenu - > addAction ( tr ( " Separated mosaics " ) ) ;
2021-01-26 19:25:57 +00:00
mosaicsSeparatedAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : SHIFT + Qt : : Key_S ) ) ;
2020-09-06 16:47:38 +01:00
mosaicsSeparatedAct - > setStatusTip ( tr ( " Insert separated mosaics attribute " ) ) ;
connect ( mosaicsSeparatedAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x1a ) ; } ) ;
2021-01-26 19:25:57 +00:00
QAction * mosaicsContiguousAct = mosaicsStyleSubMenu - > addAction ( tr ( " Contiguous mosaics " ) ) ;
mosaicsContiguousAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : Key_S ) ) ;
mosaicsContiguousAct - > setStatusTip ( tr ( " Insert contiguous mosaics attribute " ) ) ;
connect ( mosaicsContiguousAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x19 ) ; } ) ;
2020-09-06 16:47:38 +01:00
QMenu * mosaicsHoldSubMenu = insertMenu - > addMenu ( tr ( " Mosaics hold " ) ) ;
QAction * mosaicsHoldAct = mosaicsHoldSubMenu - > addAction ( tr ( " Hold mosaics " ) ) ;
2021-01-26 19:25:57 +00:00
mosaicsHoldAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : SHIFT + Qt : : Key_H ) ) ;
2020-09-06 16:47:38 +01:00
mosaicsHoldAct - > setStatusTip ( tr ( " Insert hold mosaics attribute " ) ) ;
connect ( mosaicsHoldAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x1e ) ; } ) ;
QAction * mosaicsReleaseAct = mosaicsHoldSubMenu - > addAction ( tr ( " Release mosaics " ) ) ;
2021-01-26 19:25:57 +00:00
mosaicsReleaseAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : Key_H ) ) ;
2020-09-06 16:47:38 +01:00
mosaicsReleaseAct - > setStatusTip ( tr ( " Insert release mosaics attribute " ) ) ;
connect ( mosaicsReleaseAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x1f ) ; } ) ;
QMenu * backgroundColourSubMenu = insertMenu - > addMenu ( tr ( " Background colour " ) ) ;
QAction * backgroundNewAct = backgroundColourSubMenu - > addAction ( tr ( " New background " ) ) ;
2021-01-26 19:25:57 +00:00
backgroundNewAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : SHIFT + Qt : : Key_N ) ) ;
2020-09-06 16:47:38 +01:00
backgroundNewAct - > setStatusTip ( tr ( " Insert new background attribute " ) ) ;
connect ( backgroundNewAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x1d ) ; } ) ;
QAction * backgroundBlackAct = backgroundColourSubMenu - > addAction ( tr ( " Black background " ) ) ;
2021-01-26 19:25:57 +00:00
backgroundBlackAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : Key_N ) ) ;
2020-09-06 16:47:38 +01:00
backgroundBlackAct - > setStatusTip ( tr ( " Insert black background attribute " ) ) ;
connect ( backgroundBlackAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x1c ) ; } ) ;
QMenu * textSizeSubMenu = insertMenu - > addMenu ( tr ( " Text size " ) ) ;
QAction * textSizeNormalAct = textSizeSubMenu - > addAction ( tr ( " Normal size " ) ) ;
2021-01-26 19:25:57 +00:00
textSizeNormalAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : Key_D ) ) ;
2020-09-06 16:47:38 +01:00
textSizeNormalAct - > setStatusTip ( tr ( " Insert normal size attribute " ) ) ;
connect ( textSizeNormalAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x0c ) ; } ) ;
2021-01-26 19:25:57 +00:00
QAction * textSizeDoubleHeightAct = textSizeSubMenu - > addAction ( tr ( " Double height " ) ) ;
textSizeDoubleHeightAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : SHIFT + Qt : : Key_D ) ) ;
textSizeDoubleHeightAct - > setStatusTip ( tr ( " Insert double height attribute " ) ) ;
connect ( textSizeDoubleHeightAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x0d ) ; } ) ;
QAction * textSizeDoubleWidthAct = textSizeSubMenu - > addAction ( tr ( " Double width " ) ) ;
textSizeDoubleWidthAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : CTRL + Qt : : Key_D ) ) ;
textSizeDoubleWidthAct - > setStatusTip ( tr ( " Insert double width attribute " ) ) ;
connect ( textSizeDoubleWidthAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x0e ) ; } ) ;
QAction * textSizeDoubleSizeAct = textSizeSubMenu - > addAction ( tr ( " Double size " ) ) ;
textSizeDoubleSizeAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : CTRL + Qt : : SHIFT + Qt : : Key_D ) ) ;
textSizeDoubleSizeAct - > setStatusTip ( tr ( " Insert double size attribute " ) ) ;
connect ( textSizeDoubleSizeAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x0f ) ; } ) ;
2020-09-06 16:47:38 +01:00
QAction * concealAct = insertMenu - > addAction ( tr ( " Conceal " ) ) ;
2021-01-26 19:25:57 +00:00
concealAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : Key_O ) ) ;
2020-09-06 16:47:38 +01:00
concealAct - > setStatusTip ( tr ( " Insert conceal attribute " ) ) ;
connect ( concealAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x18 ) ; } ) ;
QMenu * flashSubMenu = insertMenu - > addMenu ( tr ( " Flash " ) ) ;
QAction * flashFlashingAct = flashSubMenu - > addAction ( tr ( " Flashing " ) ) ;
2021-01-26 19:25:57 +00:00
flashFlashingAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : SHIFT + Qt : : Key_F ) ) ;
2020-09-06 16:47:38 +01:00
flashFlashingAct - > setStatusTip ( tr ( " Insert flashing attribute " ) ) ;
connect ( flashFlashingAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x08 ) ; } ) ;
QAction * flashSteadyAct = flashSubMenu - > addAction ( tr ( " Steady " ) ) ;
2021-01-26 19:25:57 +00:00
flashSteadyAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : Key_F ) ) ;
2020-09-06 16:47:38 +01:00
flashSteadyAct - > setStatusTip ( tr ( " Insert steady attribute " ) ) ;
connect ( flashSteadyAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x09 ) ; } ) ;
QMenu * boxingSubMenu = insertMenu - > addMenu ( tr ( " Box " ) ) ;
QAction * boxingStartAct = boxingSubMenu - > addAction ( tr ( " Start box " ) ) ;
2021-01-26 19:25:57 +00:00
boxingStartAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : SHIFT + Qt : : Key_X ) ) ;
2020-09-06 16:47:38 +01:00
boxingStartAct - > setStatusTip ( tr ( " Insert start box attribute " ) ) ;
connect ( boxingStartAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x0b ) ; } ) ;
QAction * boxingEndAct = boxingSubMenu - > addAction ( tr ( " End box " ) ) ;
2021-01-26 19:25:57 +00:00
boxingEndAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : Key_X ) ) ;
2020-09-06 16:47:38 +01:00
boxingEndAct - > setStatusTip ( tr ( " Insert end box attribute " ) ) ;
connect ( boxingEndAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x0a ) ; } ) ;
QAction * escSwitchAct = insertMenu - > addAction ( tr ( " ESC/switch " ) ) ;
2021-01-26 19:25:57 +00:00
escSwitchAct - > setShortcut ( QKeySequence ( Qt : : Key_Escape , Qt : : CTRL + Qt : : Key_S ) ) ;
2020-09-06 16:47:38 +01:00
escSwitchAct - > setStatusTip ( tr ( " Insert ESC/switch character set attribute " ) ) ;
connect ( escSwitchAct , & QAction : : triggered , [ = ] ( ) { m_textWidget - > setCharacter ( 0x1b ) ; } ) ;
QMenu * toolsMenu = menuBar ( ) - > addMenu ( tr ( " &Tools " ) ) ;
2020-09-08 12:12:24 +01:00
toolsMenu - > addAction ( m_pageOptionsDockWidget - > toggleViewAction ( ) ) ;
toolsMenu - > addAction ( m_x26DockWidget - > toggleViewAction ( ) ) ;
toolsMenu - > addAction ( m_pageEnhancementsDockWidget - > toggleViewAction ( ) ) ;
toolsMenu - > addAction ( m_paletteDockWidget - > toggleViewAction ( ) ) ;
2022-05-01 12:55:08 +01:00
toolsMenu - > addAction ( m_pageComposeLinksDockWidget - > toggleViewAction ( ) ) ;
2020-09-06 16:47:38 +01:00
//FIXME is this main menubar separator to put help menu towards the right?
menuBar ( ) - > addSeparator ( ) ;
QMenu * helpMenu = menuBar ( ) - > addMenu ( tr ( " &Help " ) ) ;
QAction * aboutAct = helpMenu - > addAction ( tr ( " &About " ) , this , & MainWindow : : about ) ;
aboutAct - > setStatusTip ( tr ( " Show the application's About box " ) ) ;
# ifndef QT_NO_CLIPBOARD
/*
cutAct - > setEnabled ( false ) ;
copyAct - > setEnabled ( false ) ;
connect ( textWidget , & QTextEdit : : copyAvailable , cutAct , & QAction : : setEnabled ) ;
connect ( textWidget , & QTextEdit : : copyAvailable , copyAct , & QAction : : setEnabled ) ;
*/
# endif // !QT_NO_CLIPBOARD
}
void MainWindow : : setSceneDimensions ( )
{
const int topBottomBorders [ 3 ] = { 0 , 10 , 19 } ;
2020-11-24 13:16:20 +00:00
const int pillarBoxSizes [ 3 ] = { 672 , 720 , 854 } ;
const int leftRightBorders [ 3 ] = { 0 , 24 , 77 } ;
2020-09-06 16:47:38 +01:00
int newSceneWidth ;
2020-11-24 13:16:20 +00:00
if ( m_viewAspectRatio = = 1 )
// 16:9 pillar box aspect ratio, fixed horizontal size whatever the widget width is
newSceneWidth = pillarBoxSizes [ m_viewBorder ] ;
else if ( m_viewBorder = = 2 )
// "Full TV" border, semi-fixed horizontal size to TV width
// Side panel width over 13 columns will cause this to widen a little
newSceneWidth = qMax ( 640 , m_textWidget - > width ( ) ) ;
2020-09-06 16:47:38 +01:00
else
2020-11-24 13:16:20 +00:00
newSceneWidth = m_textWidget - > width ( ) + leftRightBorders [ m_viewBorder ] * 2 ;
2022-04-02 22:38:38 +01:00
m_textScene - > setBorderDimensions ( newSceneWidth , 250 + topBottomBorders [ m_viewBorder ] * 2 , m_textWidget - > width ( ) , m_textWidget - > pageDecode ( ) - > leftSidePanelColumns ( ) , m_textWidget - > pageDecode ( ) - > rightSidePanelColumns ( ) ) ;
2020-11-24 13:16:20 +00:00
m_textView - > setTransform ( QTransform ( ( 1 + ( float ) m_viewZoom / 2 ) * aspectRatioHorizontalScaling [ m_viewAspectRatio ] , 0 , 0 , 1 + ( float ) m_viewZoom / 2 , 0 , 0 ) ) ;
2020-09-06 16:47:38 +01:00
}
2020-10-27 15:17:54 +00:00
void MainWindow : : insertRow ( bool copyRow )
{
if ( m_textWidget - > document ( ) - > cursorRow ( ) = = 24 )
return ;
2021-05-02 12:36:37 +01:00
m_textWidget - > document ( ) - > undoStack ( ) - > push ( new InsertRowCommand ( m_textWidget - > document ( ) , copyRow ) ) ;
2020-10-27 15:17:54 +00:00
}
void MainWindow : : deleteRow ( )
{
2021-05-02 12:36:37 +01:00
m_textWidget - > document ( ) - > undoStack ( ) - > push ( new DeleteRowCommand ( m_textWidget - > document ( ) ) ) ;
2020-10-27 15:17:54 +00:00
}
2020-09-06 16:47:38 +01:00
void MainWindow : : insertSubPage ( bool afterCurrentSubPage , bool copyCurrentSubPage )
{
2021-05-02 12:36:37 +01:00
m_textWidget - > document ( ) - > undoStack ( ) - > push ( new InsertSubPageCommand ( m_textWidget - > document ( ) , afterCurrentSubPage , copyCurrentSubPage ) ) ;
2020-09-06 16:47:38 +01:00
}
2020-12-15 21:57:42 +00:00
void MainWindow : : deleteSubPage ( )
{
if ( m_textWidget - > document ( ) - > numberOfSubPages ( ) = = 1 )
return ;
m_textWidget - > document ( ) - > undoStack ( ) - > push ( new DeleteSubPageCommand ( m_textWidget - > document ( ) ) ) ;
}
2020-09-06 16:47:38 +01:00
void MainWindow : : setBorder ( int newViewBorder )
{
m_viewBorder = newViewBorder ;
setSceneDimensions ( ) ;
}
void MainWindow : : setAspectRatio ( int newViewAspectRatio )
{
m_viewAspectRatio = newViewAspectRatio ;
setSceneDimensions ( ) ;
}
2021-06-07 21:58:14 +01:00
void MainWindow : : setSmoothTransform ( bool smoothTransform )
{
m_viewSmoothTransform = smoothTransform ;
if ( smoothTransform )
m_textView - > setRenderHints ( QPainter : : SmoothPixmapTransform ) ;
else
m_textView - > setRenderHints ( { } ) ;
}
2020-09-06 16:47:38 +01:00
void MainWindow : : zoomIn ( )
{
if ( m_viewZoom < 4 )
m_viewZoom + + ;
2021-09-09 21:40:36 +01:00
else if ( m_viewZoom < 12 )
m_viewZoom + = 2 ;
2020-09-06 16:47:38 +01:00
setSceneDimensions ( ) ;
}
void MainWindow : : zoomOut ( )
{
2021-09-09 21:40:36 +01:00
if ( m_viewZoom > 4 )
m_viewZoom - = 2 ;
else if ( m_viewZoom > 0 )
2020-09-06 16:47:38 +01:00
m_viewZoom - - ;
setSceneDimensions ( ) ;
}
void MainWindow : : zoomReset ( )
{
m_viewZoom = 2 ;
setSceneDimensions ( ) ;
}
2021-02-14 17:35:11 +00:00
void MainWindow : : toggleInsertMode ( )
{
m_textWidget - > setInsertMode ( ! m_textWidget - > insertMode ( ) ) ;
if ( m_textWidget - > insertMode ( ) )
m_insertModePushButton - > setText ( " INSERT " ) ;
else
m_insertModePushButton - > setText ( " OVERWRITE " ) ;
}
2020-09-06 16:47:38 +01:00
void MainWindow : : createStatusBar ( )
{
2020-12-13 15:46:23 +00:00
m_previousSubPageButton = new QToolButton ;
m_previousSubPageButton - > setAutoRaise ( true ) ;
m_previousSubPageButton - > setArrowType ( Qt : : LeftArrow ) ;
2022-02-13 18:50:50 +00:00
statusBar ( ) - > insertWidget ( 0 , m_previousSubPageButton ) ;
2020-12-13 15:46:23 +00:00
connect ( m_previousSubPageButton , & QToolButton : : clicked , m_textWidget - > document ( ) , & TeletextDocument : : selectSubPagePrevious ) ;
m_subPageLabel = new QLabel ( " 1/1 " ) ;
2022-02-13 18:50:50 +00:00
statusBar ( ) - > insertWidget ( 1 , m_subPageLabel ) ;
2020-12-13 15:46:23 +00:00
m_nextSubPageButton = new QToolButton ;
2022-02-13 18:50:50 +00:00
m_previousSubPageButton - > setMinimumSize ( m_subPageLabel - > height ( ) , m_subPageLabel - > height ( ) ) ;
m_previousSubPageButton - > setMaximumSize ( m_subPageLabel - > height ( ) , m_subPageLabel - > height ( ) ) ;
m_nextSubPageButton - > setMinimumSize ( m_subPageLabel - > height ( ) , m_subPageLabel - > height ( ) ) ;
m_nextSubPageButton - > setMaximumSize ( m_subPageLabel - > height ( ) , m_subPageLabel - > height ( ) ) ;
2020-12-13 15:46:23 +00:00
m_nextSubPageButton - > setAutoRaise ( true ) ;
m_nextSubPageButton - > setArrowType ( Qt : : RightArrow ) ;
2022-02-13 18:50:50 +00:00
statusBar ( ) - > insertWidget ( 2 , m_nextSubPageButton ) ;
2020-12-13 15:46:23 +00:00
connect ( m_nextSubPageButton , & QToolButton : : clicked , m_textWidget - > document ( ) , & TeletextDocument : : selectSubPageNext ) ;
2022-02-13 18:50:50 +00:00
m_cursorPositionLabel = new QLabel ( " 1, 1 " ) ;
statusBar ( ) - > insertWidget ( 3 , m_cursorPositionLabel ) ;
2020-12-13 15:46:23 +00:00
2021-02-14 17:35:11 +00:00
m_insertModePushButton = new QPushButton ( " OVERWRITE " ) ;
m_insertModePushButton - > setFlat ( true ) ;
m_insertModePushButton - > setFocusProxy ( m_textWidget ) ;
statusBar ( ) - > addPermanentWidget ( m_insertModePushButton ) ;
connect ( m_insertModePushButton , & QPushButton : : clicked , this , & MainWindow : : toggleInsertMode ) ;
2020-12-13 15:46:23 +00:00
statusBar ( ) - > addPermanentWidget ( new QLabel ( " Level " ) ) ;
2020-09-06 16:47:38 +01:00
2020-12-20 19:38:23 +00:00
m_levelRadioButton [ 0 ] = new QRadioButton ( " 1 " ) ;
m_levelRadioButton [ 1 ] = new QRadioButton ( " 1.5 " ) ;
m_levelRadioButton [ 2 ] = new QRadioButton ( " 2.5 " ) ;
m_levelRadioButton [ 3 ] = new QRadioButton ( " 3.5 " ) ;
2021-02-12 21:43:14 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
m_levelRadioButton [ i ] - > setFocusPolicy ( Qt : : NoFocus ) ;
statusBar ( ) - > addPermanentWidget ( m_levelRadioButton [ i ] ) ;
}
2020-12-20 19:38:23 +00:00
m_levelRadioButton [ 0 ] - > toggle ( ) ;
2022-05-02 22:24:04 +01:00
connect ( m_levelRadioButton [ 0 ] , & QAbstractButton : : clicked , [ = ] ( ) { m_textWidget - > pageDecode ( ) - > setLevel ( 0 ) ; m_textWidget - > update ( ) ; } ) ;
connect ( m_levelRadioButton [ 1 ] , & QAbstractButton : : clicked , [ = ] ( ) { m_textWidget - > pageDecode ( ) - > setLevel ( 1 ) ; m_textWidget - > update ( ) ; } ) ;
connect ( m_levelRadioButton [ 2 ] , & QAbstractButton : : clicked , [ = ] ( ) { m_textWidget - > pageDecode ( ) - > setLevel ( 2 ) ; m_textWidget - > update ( ) ; } ) ;
connect ( m_levelRadioButton [ 3 ] , & QAbstractButton : : clicked , [ = ] ( ) { m_textWidget - > pageDecode ( ) - > setLevel ( 3 ) ; m_textWidget - > update ( ) ; } ) ;
2020-09-06 16:47:38 +01:00
statusBar ( ) - > showMessage ( tr ( " Ready " ) ) ;
}
void MainWindow : : readSettings ( )
{
//TODO window sizing
QSettings settings ( QCoreApplication : : organizationName ( ) , QCoreApplication : : applicationName ( ) ) ;
const QByteArray geometry = settings . value ( " geometry " , QByteArray ( ) ) . toByteArray ( ) ;
const QByteArray windowState = settings . value ( " windowState " , QByteArray ( ) ) . toByteArray ( ) ;
m_viewBorder = settings . value ( " border " , 2 ) . toInt ( ) ;
m_viewBorder = ( m_viewBorder < 0 | | m_viewBorder > 2 ) ? 2 : m_viewBorder ;
m_borderActs [ m_viewBorder ] - > setChecked ( true ) ;
m_viewAspectRatio = settings . value ( " aspectratio " , 0 ) . toInt ( ) ;
m_viewAspectRatio = ( m_viewAspectRatio < 0 | | m_viewAspectRatio > 2 ) ? 0 : m_viewAspectRatio ;
m_aspectRatioActs [ m_viewAspectRatio ] - > setChecked ( true ) ;
2021-06-07 21:58:14 +01:00
m_viewSmoothTransform = settings . value ( " smoothTransform " , 0 ) . toBool ( ) ;
m_smoothTransformAction - > blockSignals ( true ) ;
m_smoothTransformAction - > setChecked ( m_viewSmoothTransform ) ;
m_smoothTransformAction - > blockSignals ( false ) ;
2020-09-06 16:47:38 +01:00
m_viewZoom = settings . value ( " zoom " , 2 ) . toInt ( ) ;
2021-09-09 21:40:36 +01:00
m_viewZoom = ( m_viewZoom < 0 | | m_viewZoom > 12 ) ? 2 : m_viewZoom ;
2020-09-06 16:47:38 +01:00
// zoom 0 = 420,426px, 1 = 620,570px, 2 = 780,720px
if ( geometry . isEmpty ( ) ) {
const QRect availableGeometry = QGuiApplication : : primaryScreen ( ) - > availableGeometry ( ) ;
if ( availableGeometry . width ( ) < 620 | | availableGeometry . height ( ) < 570 ) {
resize ( 430 , 430 ) ;
m_viewZoom = 0 ;
} else if ( availableGeometry . width ( ) < 780 | | availableGeometry . height ( ) < 720 ) {
resize ( 620 , 570 ) ;
m_viewZoom = 1 ;
} else
resize ( 780 , 720 ) ;
// m_viewZoom = 2;
move ( ( availableGeometry . width ( ) - width ( ) ) / 2 , ( availableGeometry . height ( ) - height ( ) ) / 2 ) ;
} else
restoreGeometry ( geometry ) ;
if ( windowState . isEmpty ( ) ) {
2020-09-08 12:12:24 +01:00
m_pageOptionsDockWidget - > hide ( ) ;
m_pageOptionsDockWidget - > setFloating ( true ) ;
m_pageEnhancementsDockWidget - > hide ( ) ;
m_pageEnhancementsDockWidget - > setFloating ( true ) ;
m_x26DockWidget - > hide ( ) ;
m_x26DockWidget - > setFloating ( true ) ;
m_paletteDockWidget - > hide ( ) ;
m_paletteDockWidget - > setFloating ( true ) ;
2022-05-01 12:55:08 +01:00
m_pageComposeLinksDockWidget - > hide ( ) ;
m_pageComposeLinksDockWidget - > setFloating ( true ) ;
2020-09-06 16:47:38 +01:00
} else
restoreState ( windowState ) ;
}
void MainWindow : : writeSettings ( )
{
QSettings settings ( QCoreApplication : : organizationName ( ) , QCoreApplication : : applicationName ( ) ) ;
settings . setValue ( " geometry " , saveGeometry ( ) ) ;
settings . setValue ( " windowState " , saveState ( ) ) ;
settings . setValue ( " border " , m_viewBorder ) ;
settings . setValue ( " aspectratio " , m_viewAspectRatio ) ;
2021-06-07 21:58:14 +01:00
settings . setValue ( " smoothTransform " , m_viewSmoothTransform ) ;
2020-09-06 16:47:38 +01:00
settings . setValue ( " zoom " , m_viewZoom ) ;
}
bool MainWindow : : maybeSave ( )
{
if ( m_textWidget - > document ( ) - > undoStack ( ) - > isClean ( ) )
return true ;
2021-12-14 22:06:18 +00:00
const QMessageBox : : StandardButton ret = QMessageBox : : warning ( this , QApplication : : applicationDisplayName ( ) , tr ( " The document \" %1 \" has been modified. \n Do you want to save your changes or discard them? " ) . arg ( QFileInfo ( m_curFile ) . fileName ( ) ) , QMessageBox : : Save | QMessageBox : : Discard | QMessageBox : : Cancel ) ;
2020-09-06 16:47:38 +01:00
switch ( ret ) {
case QMessageBox : : Save :
return save ( ) ;
case QMessageBox : : Cancel :
return false ;
default :
break ;
}
return true ;
}
void MainWindow : : loadFile ( const QString & fileName )
{
2020-12-20 19:38:23 +00:00
int levelSeen ;
2020-09-06 16:47:38 +01:00
QFile file ( fileName ) ;
2021-08-15 19:03:40 +01:00
const QFileInfo fileInfo ( file ) ;
QIODevice : : OpenMode fileOpenMode ;
if ( fileInfo . suffix ( ) = = " t42 " )
fileOpenMode = QFile : : ReadOnly ;
else
fileOpenMode = QFile : : ReadOnly | QFile : : Text ;
if ( ! file . open ( fileOpenMode ) ) {
2021-09-10 17:14:27 +01:00
QMessageBox : : warning ( this , QApplication : : applicationDisplayName ( ) , tr ( " Cannot read file %1: \n %2. " ) . arg ( QDir : : toNativeSeparators ( fileName ) , file . errorString ( ) ) ) ;
2020-09-06 16:47:38 +01:00
setCurrentFile ( QString ( ) ) ;
return ;
}
QApplication : : setOverrideCursor ( Qt : : WaitCursor ) ;
2021-08-15 19:03:40 +01:00
if ( fileInfo . suffix ( ) = = " t42 " )
importT42 ( & file , m_textWidget - > document ( ) ) ;
else
loadTTI ( & file , m_textWidget - > document ( ) ) ;
2020-12-20 19:38:23 +00:00
levelSeen = m_textWidget - > document ( ) - > levelRequired ( ) ;
m_levelRadioButton [ levelSeen ] - > toggle ( ) ;
2022-05-02 22:24:04 +01:00
m_textWidget - > pageDecode ( ) - > setLevel ( levelSeen ) ;
2020-11-29 15:41:26 +00:00
updatePageWidgets ( ) ;
2020-09-06 16:47:38 +01:00
QApplication : : restoreOverrideCursor ( ) ;
setCurrentFile ( fileName ) ;
statusBar ( ) - > showMessage ( tr ( " File loaded " ) , 2000 ) ;
}
void MainWindow : : setRecentFilesVisible ( bool visible )
{
m_recentFileSubMenuAct - > setVisible ( visible ) ;
m_recentFileSeparator - > setVisible ( visible ) ;
}
static inline QString recentFilesKey ( ) { return QStringLiteral ( " recentFileList " ) ; }
static inline QString fileKey ( ) { return QStringLiteral ( " file " ) ; }
static QStringList readRecentFiles ( QSettings & settings )
{
QStringList result ;
const int count = settings . beginReadArray ( recentFilesKey ( ) ) ;
for ( int i = 0 ; i < count ; + + i ) {
settings . setArrayIndex ( i ) ;
result . append ( settings . value ( fileKey ( ) ) . toString ( ) ) ;
}
settings . endArray ( ) ;
return result ;
}
static void writeRecentFiles ( const QStringList & files , QSettings & settings )
{
const int count = files . size ( ) ;
settings . beginWriteArray ( recentFilesKey ( ) ) ;
for ( int i = 0 ; i < count ; + + i ) {
settings . setArrayIndex ( i ) ;
settings . setValue ( fileKey ( ) , files . at ( i ) ) ;
}
settings . endArray ( ) ;
}
bool MainWindow : : hasRecentFiles ( )
{
QSettings settings ( QCoreApplication : : organizationName ( ) , QCoreApplication : : applicationName ( ) ) ;
const int count = settings . beginReadArray ( recentFilesKey ( ) ) ;
settings . endArray ( ) ;
return count > 0 ;
}
void MainWindow : : prependToRecentFiles ( const QString & fileName )
{
QSettings settings ( QCoreApplication : : organizationName ( ) , QCoreApplication : : applicationName ( ) ) ;
const QStringList oldRecentFiles = readRecentFiles ( settings ) ;
QStringList recentFiles = oldRecentFiles ;
recentFiles . removeAll ( fileName ) ;
recentFiles . prepend ( fileName ) ;
if ( oldRecentFiles ! = recentFiles )
writeRecentFiles ( recentFiles , settings ) ;
setRecentFilesVisible ( ! recentFiles . isEmpty ( ) ) ;
}
void MainWindow : : updateRecentFileActions ( )
{
QSettings settings ( QCoreApplication : : organizationName ( ) , QCoreApplication : : applicationName ( ) ) ;
const QStringList recentFiles = readRecentFiles ( settings ) ;
const int count = qMin ( int ( m_MaxRecentFiles ) , recentFiles . size ( ) ) ;
int i = 0 ;
for ( ; i < count ; + + i ) {
const QString fileName = MainWindow : : strippedName ( recentFiles . at ( i ) ) ;
m_recentFileActs [ i ] - > setText ( tr ( " &%1 %2 " ) . arg ( i + 1 ) . arg ( fileName ) ) ;
m_recentFileActs [ i ] - > setData ( recentFiles . at ( i ) ) ;
m_recentFileActs [ i ] - > setVisible ( true ) ;
}
for ( ; i < m_MaxRecentFiles ; + + i )
m_recentFileActs [ i ] - > setVisible ( false ) ;
}
void MainWindow : : openRecentFile ( )
{
if ( const QAction * action = qobject_cast < const QAction * > ( sender ( ) ) )
openFile ( action - > data ( ) . toString ( ) ) ;
}
bool MainWindow : : saveFile ( const QString & fileName )
{
2020-11-24 19:01:25 +00:00
QString errorMessage ;
2020-09-06 16:47:38 +01:00
QApplication : : setOverrideCursor ( Qt : : WaitCursor ) ;
2020-11-24 19:01:25 +00:00
QSaveFile file ( fileName ) ;
if ( file . open ( QFile : : WriteOnly | QFile : : Text ) ) {
saveTTI ( file , * m_textWidget - > document ( ) ) ;
if ( ! file . commit ( ) )
2021-09-05 18:24:51 +01:00
errorMessage = tr ( " Cannot write file %1: \n %2. " ) . arg ( QDir : : toNativeSeparators ( fileName ) , file . errorString ( ) ) ;
2020-11-24 19:01:25 +00:00
} else
errorMessage = tr ( " Cannot open file %1 for writing: \n %2. " ) . arg ( QDir : : toNativeSeparators ( fileName ) , file . errorString ( ) ) ;
2020-09-06 16:47:38 +01:00
QApplication : : restoreOverrideCursor ( ) ;
2020-11-24 19:01:25 +00:00
if ( ! errorMessage . isEmpty ( ) ) {
2021-09-10 17:14:27 +01:00
QMessageBox : : warning ( this , QApplication : : applicationDisplayName ( ) , errorMessage ) ;
2020-11-24 19:01:25 +00:00
return false ;
}
2020-09-06 16:47:38 +01:00
setCurrentFile ( fileName ) ;
statusBar ( ) - > showMessage ( tr ( " File saved " ) , 2000 ) ;
return true ;
}
2021-09-05 18:24:51 +01:00
void MainWindow : : exportT42 ( )
{
QString errorMessage ;
QString exportFileName = m_curFile ;
changeSuffixFromTTI ( exportFileName , " t42 " ) ;
exportFileName = QFileDialog : : getSaveFileName ( this , tr ( " Export t42 " ) , exportFileName , " t42 stream (*.t42) " ) ;
if ( exportFileName . isEmpty ( ) )
return ;
QApplication : : setOverrideCursor ( Qt : : WaitCursor ) ;
QSaveFile file ( exportFileName ) ;
if ( file . open ( QFile : : WriteOnly ) ) {
exportT42File ( file , * m_textWidget - > document ( ) ) ;
if ( ! file . commit ( ) )
errorMessage = tr ( " Cannot write file %1: \n %2. " ) . arg ( QDir : : toNativeSeparators ( exportFileName ) , file . errorString ( ) ) ;
} else
errorMessage = tr ( " Cannot open file %1 for writing: \n %2. " ) . arg ( QDir : : toNativeSeparators ( exportFileName ) , file . errorString ( ) ) ;
2021-09-06 22:07:14 +01:00
QApplication : : restoreOverrideCursor ( ) ;
if ( ! errorMessage . isEmpty ( ) )
2021-09-10 17:14:27 +01:00
QMessageBox : : warning ( this , QApplication : : applicationDisplayName ( ) , errorMessage ) ;
2021-09-06 22:07:14 +01:00
}
void MainWindow : : exportM29 ( )
{
QString errorMessage ;
QString exportFileName = m_curFile ;
if ( m_isUntitled | | ! QFileInfo ( m_curFile ) . exists ( ) )
exportFileName = QString ( " P%1FF.tti " ) . arg ( m_textWidget - > document ( ) - > pageNumber ( ) > > 8 , 1 , 16 ) ;
else {
exportFileName = QFileInfo ( m_curFile ) . fileName ( ) ;
// Suggest a new filename to avoid clobbering the original file
if ( QRegExp ( ( " ^[Pp]?[1-8][0-9A-Fa-f][0-9A-Fa-f] " ) ) . indexIn ( exportFileName ) ! = - 1 ) {
// Page number forms start of file name, change it to xFF
if ( exportFileName . at ( 0 ) = = ' P ' | | exportFileName . at ( 0 ) = = ' p ' ) {
exportFileName [ 2 ] = ' F ' ;
exportFileName [ 3 ] = ' F ' ;
} else {
exportFileName [ 1 ] = ' F ' ;
exportFileName [ 2 ] = ' F ' ;
}
// No page number at start of file name. Try to insert "-m29" while preserving .tti(x) suffix
} else if ( exportFileName . endsWith ( " .tti " , Qt : : CaseInsensitive ) ) {
exportFileName . chop ( 4 ) ;
exportFileName . append ( " -m29.tti " ) ;
} else if ( exportFileName . endsWith ( " .ttix " , Qt : : CaseInsensitive ) ) {
exportFileName . chop ( 5 ) ;
exportFileName . append ( " -m29.ttix " ) ;
} else
// Shouldn't get here, bit of a messy escape but still better than clobbering the original file
exportFileName . append ( " -m29.tti " ) ;
exportFileName = QDir ( QFileInfo ( m_curFile ) . absoluteDir ( ) ) . filePath ( exportFileName ) ;
}
exportFileName = QFileDialog : : getSaveFileName ( this , tr ( " Export M/29 tti " ) , exportFileName , " TTI teletext page (*.tti *.ttix) " ) ;
if ( exportFileName . isEmpty ( ) )
return ;
QApplication : : setOverrideCursor ( Qt : : WaitCursor ) ;
QSaveFile file ( exportFileName ) ;
if ( file . open ( QFile : : WriteOnly | QFile : : Text ) ) {
exportM29File ( file , * m_textWidget - > document ( ) ) ;
if ( ! file . commit ( ) )
errorMessage = tr ( " Cannot write file %1: \n %2. " ) . arg ( QDir : : toNativeSeparators ( exportFileName ) , file . errorString ( ) ) ;
} else
errorMessage = tr ( " Cannot open file %1 for writing: \n %2. " ) . arg ( QDir : : toNativeSeparators ( exportFileName ) , file . errorString ( ) ) ;
2021-09-05 18:24:51 +01:00
QApplication : : restoreOverrideCursor ( ) ;
if ( ! errorMessage . isEmpty ( ) )
2021-09-10 17:14:27 +01:00
QMessageBox : : warning ( this , QApplication : : applicationDisplayName ( ) , errorMessage ) ;
2021-09-05 18:24:51 +01:00
}
2020-09-06 16:47:38 +01:00
void MainWindow : : setCurrentFile ( const QString & fileName )
{
static int sequenceNumber = 1 ;
m_isUntitled = fileName . isEmpty ( ) ;
if ( m_isUntitled )
m_curFile = tr ( " untitled%1.tti " ) . arg ( sequenceNumber + + ) ;
else
m_curFile = QFileInfo ( fileName ) . canonicalFilePath ( ) ;
m_textWidget - > document ( ) - > undoStack ( ) - > setClean ( ) ;
if ( ! m_isUntitled & & windowFilePath ( ) ! = m_curFile )
MainWindow : : prependToRecentFiles ( m_curFile ) ;
setWindowFilePath ( m_curFile ) ;
}
QString MainWindow : : strippedName ( const QString & fullFileName )
{
return QFileInfo ( fullFileName ) . fileName ( ) ;
}
MainWindow * MainWindow : : findMainWindow ( const QString & fileName ) const
{
QString canonicalFilePath = QFileInfo ( fileName ) . canonicalFilePath ( ) ;
foreach ( QWidget * widget , QApplication : : topLevelWidgets ( ) ) {
MainWindow * mainWin = qobject_cast < MainWindow * > ( widget ) ;
if ( mainWin & & mainWin - > m_curFile = = canonicalFilePath )
return mainWin ;
}
return 0 ;
}
void MainWindow : : updateCursorPosition ( )
{
2022-02-13 18:50:50 +00:00
QString result ;
result . reserve ( 19 ) ;
if ( m_textWidget - > document ( ) - > cursorRow ( ) = = 0 )
result = QString ( " Header, %1 " ) . arg ( m_textWidget - > document ( ) - > cursorColumn ( ) ) ;
else if ( m_textWidget - > document ( ) - > cursorRow ( ) = = 24 )
result = QString ( " FLOF, %1 " ) . arg ( m_textWidget - > document ( ) - > cursorColumn ( ) ) ;
else
result = QString ( " %1, %2 " ) . arg ( m_textWidget - > document ( ) - > cursorRow ( ) ) . arg ( m_textWidget - > document ( ) - > cursorColumn ( ) ) ;
if ( m_textWidget - > document ( ) - > selectionActive ( ) )
result . append ( QString ( " (%1, %2) " ) . arg ( m_textWidget - > document ( ) - > selectionHeight ( ) ) . arg ( m_textWidget - > document ( ) - > selectionWidth ( ) ) ) ;
m_cursorPositionLabel - > setText ( result ) ;
2021-04-26 21:06:00 +01:00
m_textScene - > updateCursor ( ) ;
2021-05-09 16:34:53 +01:00
m_textView - > ensureVisible ( m_textScene - > cursorRectItem ( ) , 16 , 24 ) ;
2020-09-06 16:47:38 +01:00
}
void MainWindow : : updatePageWidgets ( )
{
2020-12-13 15:46:23 +00:00
m_subPageLabel - > setText ( QString ( " %1/%2 " ) . arg ( m_textWidget - > document ( ) - > currentSubPageIndex ( ) + 1 ) . arg ( m_textWidget - > document ( ) - > numberOfSubPages ( ) ) ) ;
m_previousSubPageButton - > setEnabled ( ! ( m_textWidget - > document ( ) - > currentSubPageIndex ( ) = = 0 ) ) ;
m_nextSubPageButton - > setEnabled ( ! ( m_textWidget - > document ( ) - > currentSubPageIndex ( ) = = ( m_textWidget - > document ( ) - > numberOfSubPages ( ) ) - 1 ) ) ;
2022-02-13 18:50:50 +00:00
updateCursorPosition ( ) ;
2020-12-15 21:57:42 +00:00
m_deleteSubPageAction - > setEnabled ( m_textWidget - > document ( ) - > numberOfSubPages ( ) > 1 ) ;
2020-09-08 12:12:24 +01:00
m_pageOptionsDockWidget - > updateWidgets ( ) ;
m_pageEnhancementsDockWidget - > updateWidgets ( ) ;
m_x26DockWidget - > loadX26List ( ) ;
m_paletteDockWidget - > updateAllColourButtons ( ) ;
2022-05-01 12:55:08 +01:00
m_pageComposeLinksDockWidget - > updateWidgets ( ) ;
2020-09-06 16:47:38 +01:00
}