File indexing completed on 2024-05-12 05:40:38
0001 /* 0002 Cahoots is a crossplatform real-time collaborative text editor. 0003 0004 Copyright (C) 2010 Chris Dimpfl, Anandi Hira, David Vega 0005 0006 This program is free software: you can redistribute it and/or modify 0007 it under the terms of the GNU General Public License as published by 0008 the Free Software Foundation, either version 3 of the License, or 0009 (at your option) any later version. 0010 0011 This program is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 GNU General Public License for more details. 0015 0016 You should have received a copy of the GNU General Public License 0017 along with this program. If not, see <http://www.gnu.org/licenses/>. 0018 */ 0019 #include "sharednote.h" 0020 0021 #include "ui_sharednote.h" 0022 #include <QCloseEvent> 0023 #include <QDebug> 0024 #include <QDesktopServices> 0025 #include <QFileInfo> 0026 #include <QFontDialog> 0027 #include <QMessageBox> 0028 #include <QPrintDialog> 0029 #include <QPrinter> 0030 #include <QScreen> 0031 #include <QTextDocument> 0032 #include <QTextDocumentFragment> 0033 0034 #include "controller/view_controller/sharednotecontroller.h" 0035 #include "document.h" 0036 #include "enu.h" 0037 #include "utilities.h" 0038 0039 SharedNote::SharedNote(SharedNoteController* ctrl, QWidget* parent) 0040 : QMainWindow(parent), m_sharedCtrl(ctrl), ui(new Ui::SharedNote) 0041 { 0042 ui->setupUi(this); 0043 0044 if(!m_sharedCtrl) 0045 return; 0046 0047 m_document= new Document(ctrl, ui->m_documentSupport); 0048 connect(m_document->getDocument(), &QTextDocument::contentsChange, this, &SharedNote::textHasChanged); 0049 auto pane= m_document->getParticipantPane(); 0050 0051 auto func= [this]() { 0052 if(!m_sharedCtrl) 0053 return; 0054 setWindowTitle(tr("%1 - Shared Note Editor").arg(m_sharedCtrl->name())); 0055 }; 0056 0057 connect(m_sharedCtrl, &SharedNoteController::nameChanged, this, func); 0058 0059 connect(pane, &ParticipantsPane::memberCanNowRead, this, &SharedNote::populateDocumentForUser); 0060 connect(pane, &ParticipantsPane::memberPermissionsChanged, this, &SharedNote::playerPermissionsChanged); 0061 connect(m_document, &Document::contentChanged, this, [this]() { setWindowModified(true); }); 0062 0063 findDialog= new FindDialog(this); 0064 connect(findDialog, &FindDialog::findDialogFindNext, this, &SharedNote::findNextTriggered); 0065 connect(findDialog, &FindDialog::findDialogFindPrev, this, &SharedNote::findPrevTriggered); 0066 connect(findDialog, &FindDialog::findDialogReplaceAll, this, &SharedNote::replaceAllTriggered); 0067 connect(findDialog, &FindDialog::findDialogReplace, this, &SharedNote::replaceTriggered); 0068 connect(findDialog, &FindDialog::findDiaalogFindReplace, this, &SharedNote::findReplaceTriggered); 0069 0070 QGridLayout* tabLayout= new QGridLayout; 0071 ui->m_documentSupport->setLayout(tabLayout); 0072 tabLayout->addWidget(m_document); 0073 tabLayout->setContentsMargins(0, 0, 0, 0); 0074 0075 auto localIsOwner= (m_sharedCtrl->ownerId() == m_sharedCtrl->localId()); 0076 0077 connect(m_document, SIGNAL(undoAvailable(bool)), this, SLOT(setUndoability(bool))); 0078 connect(m_document, SIGNAL(redoAvailable(bool)), this, SLOT(setRedoability(bool))); 0079 0080 if(localIsOwner) 0081 { 0082 connect(ui->m_showParticipants, &QAction::triggered, m_sharedCtrl, 0083 &SharedNoteController::setParticipantPanelVisible); 0084 connect(m_sharedCtrl, &SharedNoteController::participantPanelVisibleChanged, ui->m_showParticipants, 0085 &QAction::setChecked); 0086 0087 connect(m_sharedCtrl, &SharedNoteController::participantPanelVisibleChanged, pane, 0088 &ParticipantsPane::setVisible); 0089 connect(m_sharedCtrl, &SharedNoteController::participantPanelVisibleChanged, this, 0090 [this](bool b) { m_document->setParticipantsHidden(!b); }); 0091 0092 ui->m_showParticipants->setChecked(m_sharedCtrl->participantPanelVisible()); 0093 } 0094 else 0095 { 0096 ui->m_showParticipants->setChecked(false); 0097 } 0098 0099 ui->m_showParticipants->setEnabled(localIsOwner); 0100 0101 connect(ui->m_highlightMarkdownAction, &QAction::triggered, this, [this](bool b) { 0102 m_sharedCtrl->setHighligthedSyntax(b ? SharedNoteController::HighlightedSyntax::MarkDown : 0103 SharedNoteController::HighlightedSyntax::None); 0104 }); 0105 0106 connect(ui->m_markdownPreview, &QAction::triggered, m_sharedCtrl, &SharedNoteController::setMarkdownVisible); 0107 0108 pane->setVisible(m_sharedCtrl->participantPanelVisible()); 0109 0110 readSettings(); 0111 0112 func(); 0113 qApp->installEventFilter(this); 0114 } 0115 0116 SharedNote::~SharedNote() 0117 { 0118 delete ui; 0119 } 0120 0121 void SharedNote::readSettings() 0122 { 0123 QSettings settings("rolisteam", "SharedNote"); 0124 auto screen= QApplication::primaryScreen()->availableGeometry(); 0125 int width= static_cast<int>(screen.width() * 0.80); 0126 int height= static_cast<int>(screen.height() * 0.70); 0127 int screenWidth= screen.width(); 0128 int screenHeight= screen.height(); 0129 QPoint pos= settings.value("pos", QPoint((screenWidth - width) / 2, (screenHeight - height) / 2)).toPoint(); 0130 QSize size= settings.value("size", QSize(width, height)).toSize(); 0131 resize(size); 0132 move(pos); 0133 } 0134 0135 void SharedNote::writeSettings() 0136 { 0137 QSettings settings("rolisteam", "SharedNote"); 0138 settings.setValue("pos", pos()); 0139 settings.setValue("size", size()); 0140 settings.setValue("name", "user"); 0141 } 0142 0143 // Protected closeEvent 0144 void SharedNote::closeEvent(QCloseEvent*) 0145 { 0146 // bool okToQuit = true; 0147 /// @warning do something 0148 } 0149 void SharedNote::populateDocumentForUser(QString id) 0150 { 0151 /*NetworkMessageWriter msg(NetMsg::SharedNoteCategory, NetMsg::updateTextAndPermission, NetworkMessage::OneOrMany); 0152 QStringList ids; 0153 ids << id; 0154 msg.setRecipientList(ids, NetworkMessage::OneOrMany); 0155 msg.string8(m_id); 0156 m_document->fill(&msg); 0157 msg.sendToServer();*/ 0158 } 0159 0160 void SharedNote::setOwnerId(const QString& id) 0161 { 0162 updateWindowTitle(); 0163 } 0164 bool SharedNote::eventFilter(QObject*, QEvent* event) 0165 { 0166 if(event->type() == QEvent::FileOpen) 0167 { 0168 QString fileName 0169 = static_cast<QFileOpenEvent*>(event)->file(); // for the sake of mirroring code in our open slot 0170 if(!fileName.isEmpty()) 0171 { 0172 } 0173 event->accept(); 0174 return true; 0175 } 0176 return false; 0177 } 0178 0179 bool SharedNote::saveFile(QDataStream& out) 0180 { 0181 if(nullptr == m_document) 0182 return false; 0183 0184 QApplication::setOverrideCursor(Qt::WaitCursor); 0185 out << m_document->getPlainText(); 0186 QApplication::restoreOverrideCursor(); 0187 m_document->setModified(false); 0188 setWindowModified(false); 0189 return true; 0190 } 0191 0192 bool SharedNote::saveFileAsText(QTextStream& out) 0193 { 0194 if(nullptr == m_document) 0195 return false; 0196 0197 out << m_document->getPlainText(); 0198 m_document->setModified(false); 0199 setWindowModified(false); 0200 return true; 0201 } 0202 0203 bool SharedNote::loadFileAsText(QTextStream& in, bool md) 0204 { 0205 if(nullptr == m_document) 0206 return false; 0207 QString data; 0208 data= in.readAll(); 0209 m_document->setPlainText(data); 0210 if(md) 0211 m_sharedCtrl->setHighligthedSyntax(SharedNoteController::HighlightedSyntax::MarkDown); 0212 0213 return true; 0214 } 0215 0216 bool SharedNote::loadFile(QDataStream& in) 0217 { 0218 if(nullptr == m_document) 0219 return false; 0220 0221 QString data; 0222 in >> data; 0223 m_document->setPlainText(data); 0224 return true; 0225 } 0226 0227 QString SharedNote::strippedName(const QString& fullFileName) 0228 { 0229 return QFileInfo(fullFileName).fileName(); 0230 } 0231 0232 void SharedNote::on_actionFile_Print_triggered() 0233 { 0234 QTextDocument document(m_document->getPlainText(), this); 0235 document.setDefaultFont(QFont("Courier", 10, -1)); 0236 0237 QPrinter printer(QPrinter::HighResolution); 0238 0239 QPrintDialog* dialog= new QPrintDialog(&printer, this); 0240 dialog->setWindowTitle("Print"); 0241 if(dialog->exec() == QDialog::Accepted) 0242 { 0243 document.print(&printer); 0244 } 0245 } 0246 0247 // Edit menu items 0248 void SharedNote::on_actionEdit_Undo_triggered() 0249 { 0250 m_document->undo(); 0251 } 0252 0253 void SharedNote::on_actionEdit_Redo_triggered() 0254 { 0255 m_document->redo(); 0256 } 0257 0258 void SharedNote::on_actionEdit_Cut_triggered() 0259 { 0260 m_document->cut(); 0261 } 0262 0263 void SharedNote::on_actionEdit_Copy_triggered() 0264 { 0265 m_document->copy(); 0266 } 0267 0268 void SharedNote::on_actionEdit_Paste_triggered() 0269 { 0270 m_document->paste(); 0271 } 0272 0273 void SharedNote::on_actionEdit_Find_All_triggered() 0274 { 0275 m_document->findAll(); 0276 } 0277 0278 void SharedNote::on_actionEdit_Find_triggered() 0279 { 0280 findDialog->show(); 0281 } 0282 0283 void SharedNote::on_actionView_Line_Wrap_triggered() 0284 { 0285 m_document->toggleLineWrap(); 0286 } 0287 0288 //#include "userlist/playersList.h" 0289 void SharedNote::textHasChanged(int pos, int charsRemoved, int charsAdded) 0290 { 0291 if(!m_sharedCtrl->localCanWrite()) 0292 return; 0293 0294 QString toSend; 0295 QString data; 0296 0297 if(charsRemoved > 0 && charsAdded == 0) 0298 { 0299 data= ""; 0300 } 0301 else if(charsAdded > 0) 0302 { 0303 QTextCursor cursor= QTextCursor(m_document->getDocument()); 0304 cursor.setPosition(pos, QTextCursor::MoveAnchor); 0305 cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, charsAdded); 0306 data= cursor.selection().toPlainText(); 0307 } 0308 0309 toSend= QString("doc:%1 %2 %3 %4").arg(pos).arg(charsRemoved).arg(charsAdded).arg(data); 0310 0311 m_sharedCtrl->setTextUpdate(toSend); 0312 } 0313 0314 void SharedNote::displaySharingPanel() 0315 { 0316 m_document->displayParticipantPanel(); 0317 } 0318 0319 void SharedNote::updateDocumentToAll(NetworkMessageWriter* msg) 0320 { 0321 /* if(nullptr != m_document) 0322 { 0323 m_document->fill(msg); 0324 }*/ 0325 } 0326 0327 void SharedNote::on_actionText_Shift_Left_triggered() 0328 { 0329 m_document->shiftLeft(); 0330 } 0331 0332 void SharedNote::on_actionText_Shift_Right_triggered() 0333 { 0334 m_document->shiftRight(); 0335 } 0336 0337 void SharedNote::on_actionText_Comment_Line_triggered() 0338 { 0339 m_document->unCommentSelection(); 0340 } 0341 0342 void SharedNote::setUndoability(bool b) 0343 { 0344 if(sender() == m_document) 0345 { 0346 ui->actionEdit_Undo->setEnabled(b); 0347 } 0348 } 0349 0350 void SharedNote::setRedoability(bool b) 0351 { 0352 if(sender() == m_document) 0353 { 0354 ui->actionEdit_Redo->setEnabled(b); 0355 } 0356 } 0357 0358 void SharedNote::documentChanged() 0359 { 0360 Document* document= m_document; 0361 ui->actionEdit_Undo->setEnabled(document->isUndoable()); 0362 ui->actionEdit_Redo->setEnabled(document->isRedoable()); 0363 // ui->actionWindow_Split->setDisabled(document->isEditorSplit() && !document->isEditorSplitSideBySide()); 0364 // ui->actionWindow_Split_Side_by_Side->setDisabled(document->isEditorSplit() && 0365 // document->isEditorSplitSideBySide()); 0366 0367 // ui->actionWindow_Remove_Split->setEnabled(document->isEditorSplit()); 0368 ui->actionTools_Announce_Document->setDisabled(document->docHasCollaborated()); 0369 } 0370 0371 void SharedNote::tabCloseClicked() 0372 { 0373 /* if (maybeSave(index)) { 0374 if (ui->tabWidget->count() == 1) { 0375 on_actionFile_New_triggered(); 0376 } 0377 ui->tabWidget->widget(index)->deleteLater(); 0378 tabWidgetToDocumentMap.remove(ui->tabWidget->widget(index)); 0379 ui->tabWidget->removeTab(index); 0380 }*/ 0381 } 0382 0383 void SharedNote::findNextTriggered(QString str, Qt::CaseSensitivity sensitivity, bool wrapAround, Enu::FindMode mode) 0384 { 0385 m_document->findNext(str, sensitivity, wrapAround, mode); 0386 } 0387 0388 void SharedNote::findPrevTriggered(QString str, Qt::CaseSensitivity sensitivity, bool wrapAround, Enu::FindMode mode) 0389 { 0390 m_document->findPrev(str, sensitivity, wrapAround, mode); 0391 } 0392 0393 void SharedNote::replaceAllTriggered(QString find, QString replace, Qt::CaseSensitivity sensitivity, Enu::FindMode mode) 0394 { 0395 m_document->replaceAll(find, replace, sensitivity, mode); 0396 } 0397 0398 void SharedNote::replaceTriggered(QString replace) 0399 { 0400 m_document->replace(replace); 0401 } 0402 0403 void SharedNote::findReplaceTriggered(QString find, QString replace, Qt::CaseSensitivity sensitivity, bool wrapAround, 0404 Enu::FindMode mode) 0405 { 0406 m_document->findReplace(find, replace, sensitivity, wrapAround, mode); 0407 } 0408 0409 void SharedNote::playerPermissionsChanged(QString id, int perm) 0410 { 0411 // QString toSend = QString("updateperm:%1").arg(permissions); 0412 /*NetworkMessageWriter msg(NetMsg::SharedNoteCategory, NetMsg::updatePermissionOneUser); 0413 msg.string8(m_id); // MediaId 0414 msg.string8(id); // playerId 0415 msg.int8(perm); // Permission 0416 msg.sendToServer();*/ 0417 } 0418 0419 void SharedNote::setEditorFont(QFont font) 0420 { 0421 m_document->setEditorFont(font); 0422 } 0423 0424 void SharedNote::setParticipantsFont(QFont font) 0425 { 0426 m_document->setParticipantsFont(font); 0427 } 0428 0429 QString SharedNote::id() const 0430 { 0431 return m_id; 0432 } 0433 0434 void SharedNote::setId(const QString& id) 0435 { 0436 m_id= id; 0437 } 0438 0439 void SharedNote::updateWindowTitle() 0440 { 0441 0442 /*PlayerModel* list= PlayerModel::instance(); 0443 Player* player= list->getLocalPlayer(); 0444 setWindowTitle( 0445 tr("%1[*] - SharedNote - %2").arg(m_fileName, m_document->canWrite(player) ? tr("ReadWrite") : 0446 tr("ReadOnly")));*/ 0447 } 0448 0449 void SharedNote::on_m_markdownPreview_triggered() 0450 { 0451 if(nullptr == m_document) 0452 return; 0453 0454 m_document->renderMarkdown(); 0455 }